summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Leino <aleino@nvidia.com>2025-01-09 07:43:31 +0200
committerGitHub <noreply@github.com>2025-01-08 21:43:31 -0800
commitdab6cec1ed78a545c127adc0e8dbdf1f253f9132 (patch)
tree6cd0a310932b84984d4f9fd94aada408e041e64a
parent2249d6ffb19e4db8580c76ccb04ab4ca3ddc8394 (diff)
Add parentheses to make precedence explicit (#6030)
* Add parentheses to make precedence explicit Add parentheses for a few cases that Dawn/Tint (WGSL compiler) complains about. Closes #6005. * format code --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> Co-authored-by: Yong He <yonghe@outlook.com>
-rw-r--r--source/slang/slang-emit-c-like.cpp28
-rw-r--r--tests/wgsl/operator-precedence.slang45
-rw-r--r--tests/wgsl/operator-precedence.slang.expected.txt20
3 files changed, 93 insertions, 0 deletions
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index 64cc9969c..7ed4d2e4c 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -705,6 +705,34 @@ bool CLikeSourceEmitter::maybeEmitParens(EmitOpInfo& outerPrec, const EmitOpInfo
{
needParens = true;
}
+ // a ^ b + c => a ^ (b + c)
+ else if (
+ prec.leftPrecedence == EPrecedence::kEPrecedence_Additive_Left &&
+ outerPrec.leftPrecedence == EPrecedence::kEPrecedence_BitXor_Right)
+ {
+ needParens = true;
+ }
+ // a + b ^ c => (a + b) ^ c
+ else if (
+ prec.rightPrecedence == EPrecedence::kEPrecedence_Additive_Right &&
+ outerPrec.rightPrecedence == EPrecedence::kEPrecedence_BitXor_Left)
+ {
+ needParens = true;
+ }
+ // a | b + c => a | (b + c)
+ else if (
+ prec.leftPrecedence == EPrecedence::kEPrecedence_Additive_Left &&
+ outerPrec.leftPrecedence == EPrecedence::kEPrecedence_BitOr_Right)
+ {
+ needParens = true;
+ }
+ // a + b | c => (a + b) | c
+ else if (
+ prec.rightPrecedence == EPrecedence::kEPrecedence_Additive_Right &&
+ outerPrec.rightPrecedence == EPrecedence::kEPrecedence_BitOr_Left)
+ {
+ needParens = true;
+ }
if (needParens)
{
diff --git a/tests/wgsl/operator-precedence.slang b/tests/wgsl/operator-precedence.slang
new file mode 100644
index 000000000..8e90991d6
--- /dev/null
+++ b/tests/wgsl/operator-precedence.slang
@@ -0,0 +1,45 @@
+//TEST(compute):COMPARE_COMPUTE:-shaderobj
+
+//TEST_INPUT:ubuffer(data=[3 7 8], stride=4):name=inputBuffer
+RWStructuredBuffer<uint> inputBuffer;
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], stride=4):out,name=outputBuffer
+RWStructuredBuffer<uint> outputBuffer;
+
+[numthreads(1,1,1)]
+void computeMain()
+{
+ uint a = inputBuffer[0];
+ uint b = inputBuffer[1];
+ uint c = inputBuffer[2];
+
+ outputBuffer[0] = a+b ^ c;
+ outputBuffer[1] = a ^ b+c;
+
+ outputBuffer[2] = a-b | c;
+ outputBuffer[3] = a | b-c;
+
+ outputBuffer[4] = a+b & c;
+ outputBuffer[5] = a & b+c;
+
+ outputBuffer[6] = a<<b ^ c;
+ outputBuffer[7] = a ^ b<<c;
+
+ outputBuffer[8] = a>>b | c;
+ outputBuffer[9] = a | b>>c;
+
+ outputBuffer[10] = a<<b & c;
+ outputBuffer[11] = a & b<<c;
+
+ outputBuffer[12] = a<b && b!=c;
+ outputBuffer[13] = a==b || b>=c;
+
+ outputBuffer[14] = a*b ^ c;
+ outputBuffer[15] = a ^ b*c;
+
+ outputBuffer[16] = a/b | c;
+ outputBuffer[17] = a | b/c;
+
+ outputBuffer[18] = a*b & c;
+ outputBuffer[19] = a & b*c;
+}
diff --git a/tests/wgsl/operator-precedence.slang.expected.txt b/tests/wgsl/operator-precedence.slang.expected.txt
new file mode 100644
index 000000000..ba2e4b9ab
--- /dev/null
+++ b/tests/wgsl/operator-precedence.slang.expected.txt
@@ -0,0 +1,20 @@
+2
+C
+FFFFFFFC
+FFFFFFFF
+8
+3
+188
+703
+8
+3
+0
+0
+1
+0
+1D
+3B
+8
+3
+0
+0