summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulius Ikkala <julius.ikkala@gmail.com>2025-04-21 19:48:29 +0300
committerGitHub <noreply@github.com>2025-04-21 09:48:29 -0700
commit0f6ba14765bf19464a2d05fc02f596b9db6c7025 (patch)
tree50b536c603a1c3fb63842cf211cd488b89bc580a
parent043278a527ab5744674417a08d924c67a60a486b (diff)
Allow simplifying self-referential Phi parameters (#6870)
-rw-r--r--source/slang/slang-ir-simplify-cfg.cpp11
-rw-r--r--tests/bugs/gh-6860.slang20
-rw-r--r--tests/bugs/gh-6862.slang29
3 files changed, 56 insertions, 4 deletions
diff --git a/source/slang/slang-ir-simplify-cfg.cpp b/source/slang/slang-ir-simplify-cfg.cpp
index 280874f74..2310a5cce 100644
--- a/source/slang/slang-ir-simplify-cfg.cpp
+++ b/source/slang/slang-ir-simplify-cfg.cpp
@@ -728,9 +728,9 @@ static bool simplifyBoolPhiParams(IRBlock* block)
static bool removeTrivialPhiParams(IRBlock* block)
{
- // We can remove a phi parmeter if:
- // 1. all arguments to a parameter is the same (not really a phi).
- // 2. the arguments to the parameter is always the same as arguments to another existing
+ // We can remove a phi parameter if:
+ // 1. all non-self-referential arguments to a parameter are the same (not really a phi).
+ // 2. the arguments to the parameter are always the same as arguments to another existing
// parameter (duplicate phi).
bool changed = false;
@@ -765,7 +765,10 @@ static bool removeTrivialPhiParams(IRBlock* block)
termInsts.add(termInst);
for (UInt i = 0; i < termInst->getArgCount(); i++)
{
- if (args[i].areKnownValueSame)
+ // Self-referential parameters can be skipped, as they cannot
+ // introduce a new value. The phi can only have multiple different
+ // values if non-self-referential arguments differ.
+ if (args[i].areKnownValueSame && termInst->getArg(i) != params[i])
{
if (args[i].knownValue == nullptr)
args[i].knownValue = termInst->getArg(i);
diff --git a/tests/bugs/gh-6860.slang b/tests/bugs/gh-6860.slang
new file mode 100644
index 000000000..13a7e329a
--- /dev/null
+++ b/tests/bugs/gh-6860.slang
@@ -0,0 +1,20 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv
+// CHECK: OpEntryPoint
+func breaker()->float {
+ var x: float;
+ for (int i = 0; i < 1; ++i) {
+ if (true) {
+ } else {
+ x = 0.0;
+ }
+ }
+ return x;
+}
+
+[shader("fragment")]
+float4 fragment(float4 in: SV_Position)
+ : SV_Target
+{
+ let res = breaker();
+ return float4(0, 0, 0, 0);
+}
diff --git a/tests/bugs/gh-6862.slang b/tests/bugs/gh-6862.slang
new file mode 100644
index 000000000..8b65b2f2a
--- /dev/null
+++ b/tests/bugs/gh-6862.slang
@@ -0,0 +1,29 @@
+//TEST:SIMPLE(filecheck=CHECK):-stage fragment -entry fragment -target wgsl
+
+func dummy(b: StructuredBuffer<float>)->float {
+ return 0;
+}
+
+func breaker(b: StructuredBuffer<float>)->float {
+ // CHECK-NOT: var<storage, read> {{.*}} : array<f32> = {{.*}};
+ var x: float = 0;
+ for (int i = 0; i < 1; ++i) {
+ x = dummy(b);
+ if (true) {
+ } else {
+ return 0;
+ x = 0;
+ }
+ }
+ return x;
+}
+
+StructuredBuffer<float> b;
+
+[shader("fragment")]
+float4 fragment(float4 in: SV_Position)
+ : SV_Target
+{
+ let res = breaker(b);
+ return float4(res, 0, 0, 0);
+}