diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2020-04-09 15:43:09 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-09 15:43:09 -0400 |
| commit | a01c09c3934d3f859bf4bea6b4e583f25291b643 (patch) | |
| tree | 47b01ad7a3b138c46ca0f7904415a5ad6a74bb72 | |
| parent | 78acd326a0dd684dd16f1db55bd53937fc38d467 (diff) | |
Literal folding on other operators (#1314)
* Fold prefix operators if they prefix an int literal.
* Make test case a bit more convoluted.
* Remove ++ and -- as not appropriate for folding of literals.
* Set output buffer name.
| -rw-r--r-- | source/slang/slang-parser.cpp | 61 | ||||
| -rw-r--r-- | tests/compute/static-const-array.slang | 6 | ||||
| -rw-r--r-- | tests/compute/static-const-vector-array.slang | 33 | ||||
| -rw-r--r-- | tests/compute/static-const-vector-array.slang.expected.txt | 9 |
4 files changed, 93 insertions, 16 deletions
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index 4ce4c49b5..170178932 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -4706,29 +4706,63 @@ namespace Slang } } + static IRIntegerValue _foldIntegerPrefixOp(TokenType tokenType, IRIntegerValue value) + { + switch (tokenType) + { + case TokenType::OpNot: return !value; + case TokenType::OpBitNot: return ~value; + case TokenType::OpAdd: return value; + case TokenType::OpSub: return -value; + default: + { + SLANG_ASSERT(!"Unexpected op"); + return value; + } + } + } + + static IRFloatingPointValue _foldFloatPrefixOp(TokenType tokenType, IRFloatingPointValue value) + { + switch (tokenType) + { + case TokenType::OpNot: return !value; + case TokenType::OpAdd: return value; + case TokenType::OpSub: return -value; + default: + { + SLANG_ASSERT(!"Unexpected op"); + return value; + } + } + } + static RefPtr<Expr> parsePrefixExpr(Parser* parser) { - switch( peekTokenType(parser) ) + auto tokenType = peekTokenType(parser); + switch( tokenType ) { default: return parsePostfixExpr(parser); + case TokenType::OpInc: case TokenType::OpDec: + { + RefPtr<PrefixExpr> prefixExpr = new PrefixExpr(); + parser->FillPosition(prefixExpr.Ptr()); + prefixExpr->FunctionExpr = parseOperator(parser); + + auto arg = parsePrefixExpr(parser); + + prefixExpr->Arguments.add(arg); + return prefixExpr; + } case TokenType::OpNot: case TokenType::OpBitNot: case TokenType::OpAdd: - { - RefPtr<PrefixExpr> prefixExpr = new PrefixExpr(); - parser->FillPosition(prefixExpr.Ptr()); - prefixExpr->FunctionExpr = parseOperator(parser); - prefixExpr->Arguments.add(parsePrefixExpr(parser)); - return prefixExpr; - } case TokenType::OpSub: { - // Special case prefix sub (aka neg), so if it's on a literal, it produces a new literal - RefPtr<PrefixExpr> prefixExpr = new PrefixExpr(); parser->FillPosition(prefixExpr.Ptr()); prefixExpr->FunctionExpr = parseOperator(parser); @@ -4739,7 +4773,7 @@ namespace Slang { RefPtr<IntegerLiteralExpr> newLiteral = new IntegerLiteralExpr(*intLit); - IRIntegerValue value = -newLiteral->value; + IRIntegerValue value = _foldIntegerPrefixOp(tokenType, newLiteral->value); // Need to get the basic type, so we can fit to underlying type if (auto basicExprType = as<BasicExpressionType>(intLit->type.type)) @@ -4753,13 +4787,14 @@ namespace Slang else if (auto floatLit = as<FloatingPointLiteralExpr>(arg)) { RefPtr<FloatingPointLiteralExpr> newLiteral = new FloatingPointLiteralExpr(*floatLit); - newLiteral->value = -newLiteral->value; + newLiteral->value = _foldFloatPrefixOp(tokenType, floatLit->value); return newLiteral; } - + prefixExpr->Arguments.add(arg); return prefixExpr; } + break; } } diff --git a/tests/compute/static-const-array.slang b/tests/compute/static-const-array.slang index 4bd197a05..1f111e364 100644 --- a/tests/compute/static-const-array.slang +++ b/tests/compute/static-const-array.slang @@ -1,10 +1,10 @@ // static-const-array.slang //TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -//TEST_DISABLED(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute +//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute +//TEST(compute):COMPARE_COMPUTE_EX:-cpu -slang -compute - -//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out, name outputBuffer RWStructuredBuffer<int> outputBuffer; static const int kArray[] = { 16, 1, 32, 2 }; diff --git a/tests/compute/static-const-vector-array.slang b/tests/compute/static-const-vector-array.slang new file mode 100644 index 000000000..4d9234a70 --- /dev/null +++ b/tests/compute/static-const-vector-array.slang @@ -0,0 +1,33 @@ +// static-const-array.slang + +//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -output-using-type +//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute -output-using-type +//TEST(compute):COMPARE_COMPUTE_EX:-cpu -slang -compute -output-using-type + +//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0], stride=4):out, name outputBuffer +RWStructuredBuffer<float> outputBuffer; + +static const float3 kArray[8] = +{ + float3(-0.4706069, -0.4427112, - - + 0.6461146), + float3(-0.9057375, +0.3003471, +0.9542373), + float3(-0.3487388, +0.4037880, +0.5335386), + float3(+0.1023042, +0.6439373, +0.6520134), + float3(+0.5699277, +0.3513750, +0.6695386), + float3(+0.2939128, -0.1131226, +0.3149309), + float3(+0.7836658, -0.4208784, +0.8895339), + float3(+0.1564120, -0.8198990, +0.8346850) +}; + +float test(int val) +{ + return kArray[val].x + kArray[val].y + kArray[val].z; +} + +[numthreads(8, 1, 1)] +void computeMain(uint3 tid : SV_DispatchThreadID) +{ + int inVal = tid.x; + float outVal = test(inVal); + outputBuffer[inVal] = outVal; +}
\ No newline at end of file diff --git a/tests/compute/static-const-vector-array.slang.expected.txt b/tests/compute/static-const-vector-array.slang.expected.txt new file mode 100644 index 000000000..54ecdf414 --- /dev/null +++ b/tests/compute/static-const-vector-array.slang.expected.txt @@ -0,0 +1,9 @@ +type: float +-0.267204 +0.348847 +0.588588 +1.398255 +1.590841 +0.495721 +1.252321 +0.171198 |
