HLSL-IR: run DemoteToHelper even earlier

Run DemoteToHelper before DirectVariableAccess and
DecomposeStorageAccess, which both introduce non-core instructions.

Bug: 357878226
Change-Id: I52f986e2b4fd11cfdf07a2039a398e79d25d3b8b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/213454
Auto-Submit: Antonio Maiorano <amaiorano@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/hlsl/writer/raise/raise.cc b/src/tint/lang/hlsl/writer/raise/raise.cc
index f526849..90bdaea 100644
--- a/src/tint/lang/hlsl/writer/raise/raise.cc
+++ b/src/tint/lang/hlsl/writer/raise/raise.cc
@@ -179,6 +179,10 @@
         RUN_TRANSFORM(raise::ShaderIO, module, config);
     }
 
+    // DemoteToHelper must come before any transform that introduces non-core instructions.
+    // Run after ShaderIO to ensure the discards are added to the entry point it introduces.
+    RUN_TRANSFORM(core::ir::transform::DemoteToHelper, module);
+
     RUN_TRANSFORM(core::ir::transform::DirectVariableAccess, module,
                   core::ir::transform::DirectVariableAccessOptions{});
     // DecomposeStorageAccess must come after Robustness and DirectVariableAccess
@@ -193,12 +197,6 @@
         RUN_TRANSFORM(raise::PixelLocal, module, config);
     }
 
-    // TODO(dsinclair): TruncateInterstageVariables
-
-    // DemoteToHelper must come before any transform that introduces non-core instructions.
-    // Run after ShaderIO to ensure the discards are added to the entry point it introduces.
-    RUN_TRANSFORM(core::ir::transform::DemoteToHelper, module);
-
     RUN_TRANSFORM(raise::BinaryPolyfill, module);
     // BuiltinPolyfill must come after BinaryPolyfill and DecomposeStorageAccess as they add
     // builtins
diff --git a/test/tint/bug/tint/2147.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/2147.wgsl.expected.ir.dxc.hlsl
index a3c0c3e..f49918c 100644
--- a/test/tint/bug/tint/2147.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/2147.wgsl.expected.ir.dxc.hlsl
@@ -14,19 +14,24 @@
   if (false) {
     continue_execution = false;
   }
-  int v = int(0);
-  S.InterlockedCompareExchange(int(0u), int(0), int(1), v);
-  int v_1 = v;
-  atomic_compare_exchange_result_i32 v_2 = {v_1, (v_1 == int(0))};
-  int old_value = v_2.old_value;
+  atomic_compare_exchange_result_i32 v = (atomic_compare_exchange_result_i32)0;
+  if (continue_execution) {
+    int v_1 = int(0);
+    S.InterlockedCompareExchange(int(0u), int(0), int(1), v_1);
+    int v_2 = v_1;
+    atomic_compare_exchange_result_i32 v_3 = {v_2, (v_2 == int(0))};
+    v = v_3;
+  }
+  atomic_compare_exchange_result_i32 v_4 = v;
+  int old_value = v_4.old_value;
   return float4((float(old_value)).xxxx);
 }
 
 main_outputs main() {
-  main_outputs v_3 = {main_inner()};
+  main_outputs v_5 = {main_inner()};
   if (!(continue_execution)) {
     discard;
   }
-  return v_3;
+  return v_5;
 }
 
diff --git a/test/tint/bug/tint/2147.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/2147.wgsl.expected.ir.fxc.hlsl
index a3c0c3e..f49918c 100644
--- a/test/tint/bug/tint/2147.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/2147.wgsl.expected.ir.fxc.hlsl
@@ -14,19 +14,24 @@
   if (false) {
     continue_execution = false;
   }
-  int v = int(0);
-  S.InterlockedCompareExchange(int(0u), int(0), int(1), v);
-  int v_1 = v;
-  atomic_compare_exchange_result_i32 v_2 = {v_1, (v_1 == int(0))};
-  int old_value = v_2.old_value;
+  atomic_compare_exchange_result_i32 v = (atomic_compare_exchange_result_i32)0;
+  if (continue_execution) {
+    int v_1 = int(0);
+    S.InterlockedCompareExchange(int(0u), int(0), int(1), v_1);
+    int v_2 = v_1;
+    atomic_compare_exchange_result_i32 v_3 = {v_2, (v_2 == int(0))};
+    v = v_3;
+  }
+  atomic_compare_exchange_result_i32 v_4 = v;
+  int old_value = v_4.old_value;
   return float4((float(old_value)).xxxx);
 }
 
 main_outputs main() {
-  main_outputs v_3 = {main_inner()};
+  main_outputs v_5 = {main_inner()};
   if (!(continue_execution)) {
     discard;
   }
-  return v_3;
+  return v_5;
 }
 
diff --git a/test/tint/statements/discard/atomic_cmpxchg.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/discard/atomic_cmpxchg.wgsl.expected.ir.dxc.hlsl
index e5b7bee..57c824b 100644
--- a/test/tint/statements/discard/atomic_cmpxchg.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/discard/atomic_cmpxchg.wgsl.expected.ir.dxc.hlsl
@@ -13,10 +13,15 @@
 int foo_inner() {
   continue_execution = false;
   int x = int(0);
-  int v = int(0);
-  a.InterlockedCompareExchange(int(0u), int(0), int(1), v);
-  int v_1 = v;
-  atomic_compare_exchange_result_i32 result = {v_1, (v_1 == int(0))};
+  atomic_compare_exchange_result_i32 v = (atomic_compare_exchange_result_i32)0;
+  if (continue_execution) {
+    int v_1 = int(0);
+    a.InterlockedCompareExchange(int(0u), int(0), int(1), v_1);
+    int v_2 = v_1;
+    atomic_compare_exchange_result_i32 v_3 = {v_2, (v_2 == int(0))};
+    v = v_3;
+  }
+  atomic_compare_exchange_result_i32 result = v;
   if (result.exchanged) {
     x = result.old_value;
   }
@@ -24,10 +29,10 @@
 }
 
 foo_outputs foo() {
-  foo_outputs v_2 = {foo_inner()};
+  foo_outputs v_4 = {foo_inner()};
   if (!(continue_execution)) {
     discard;
   }
-  return v_2;
+  return v_4;
 }
 
diff --git a/test/tint/statements/discard/atomic_cmpxchg.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/discard/atomic_cmpxchg.wgsl.expected.ir.fxc.hlsl
index e5b7bee..57c824b 100644
--- a/test/tint/statements/discard/atomic_cmpxchg.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/discard/atomic_cmpxchg.wgsl.expected.ir.fxc.hlsl
@@ -13,10 +13,15 @@
 int foo_inner() {
   continue_execution = false;
   int x = int(0);
-  int v = int(0);
-  a.InterlockedCompareExchange(int(0u), int(0), int(1), v);
-  int v_1 = v;
-  atomic_compare_exchange_result_i32 result = {v_1, (v_1 == int(0))};
+  atomic_compare_exchange_result_i32 v = (atomic_compare_exchange_result_i32)0;
+  if (continue_execution) {
+    int v_1 = int(0);
+    a.InterlockedCompareExchange(int(0u), int(0), int(1), v_1);
+    int v_2 = v_1;
+    atomic_compare_exchange_result_i32 v_3 = {v_2, (v_2 == int(0))};
+    v = v_3;
+  }
+  atomic_compare_exchange_result_i32 result = v;
   if (result.exchanged) {
     x = result.old_value;
   }
@@ -24,10 +29,10 @@
 }
 
 foo_outputs foo() {
-  foo_outputs v_2 = {foo_inner()};
+  foo_outputs v_4 = {foo_inner()};
   if (!(continue_execution)) {
     discard;
   }
-  return v_2;
+  return v_4;
 }
 
diff --git a/test/tint/statements/discard/atomic_in_for_loop_continuing.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/discard/atomic_in_for_loop_continuing.wgsl.expected.ir.dxc.hlsl
index 9675161..7ed4a57 100644
--- a/test/tint/statements/discard/atomic_in_for_loop_continuing.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/discard/atomic_in_for_loop_continuing.wgsl.expected.ir.dxc.hlsl
@@ -31,7 +31,11 @@
       result = (result + i);
       {
         int v = int(0);
-        a.InterlockedAdd(int(0u), int(1), v);
+        if (continue_execution) {
+          int v_1 = int(0);
+          a.InterlockedAdd(int(0u), int(1), v_1);
+          v = v_1;
+        }
         i = v;
       }
       continue;
@@ -41,10 +45,10 @@
 }
 
 foo_outputs foo(foo_inputs inputs) {
-  foo_outputs v_1 = {foo_inner(inputs.tint_symbol, inputs.coord)};
+  foo_outputs v_2 = {foo_inner(inputs.tint_symbol, inputs.coord)};
   if (!(continue_execution)) {
     discard;
   }
-  return v_1;
+  return v_2;
 }
 
diff --git a/test/tint/statements/discard/atomic_in_for_loop_continuing.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/discard/atomic_in_for_loop_continuing.wgsl.expected.ir.fxc.hlsl
index 9675161..7ed4a57 100644
--- a/test/tint/statements/discard/atomic_in_for_loop_continuing.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/discard/atomic_in_for_loop_continuing.wgsl.expected.ir.fxc.hlsl
@@ -31,7 +31,11 @@
       result = (result + i);
       {
         int v = int(0);
-        a.InterlockedAdd(int(0u), int(1), v);
+        if (continue_execution) {
+          int v_1 = int(0);
+          a.InterlockedAdd(int(0u), int(1), v_1);
+          v = v_1;
+        }
         i = v;
       }
       continue;
@@ -41,10 +45,10 @@
 }
 
 foo_outputs foo(foo_inputs inputs) {
-  foo_outputs v_1 = {foo_inner(inputs.tint_symbol, inputs.coord)};
+  foo_outputs v_2 = {foo_inner(inputs.tint_symbol, inputs.coord)};
   if (!(continue_execution)) {
     discard;
   }
-  return v_1;
+  return v_2;
 }
 
diff --git a/test/tint/statements/discard/helper_functions.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/discard/helper_functions.wgsl.expected.ir.dxc.hlsl
index d9c83ad..4e04e89 100644
--- a/test/tint/statements/discard/helper_functions.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/discard/helper_functions.wgsl.expected.ir.dxc.hlsl
@@ -9,7 +9,10 @@
 }
 
 void bar() {
-  output.Store(0u, asuint(ddx(1.0f)));
+  float v = ddx(1.0f);
+  if (continue_execution) {
+    output.Store(0u, asuint(v));
+  }
 }
 
 void main() {
diff --git a/test/tint/statements/discard/helper_functions.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/discard/helper_functions.wgsl.expected.ir.fxc.hlsl
index d9c83ad..4e04e89 100644
--- a/test/tint/statements/discard/helper_functions.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/discard/helper_functions.wgsl.expected.ir.fxc.hlsl
@@ -9,7 +9,10 @@
 }
 
 void bar() {
-  output.Store(0u, asuint(ddx(1.0f)));
+  float v = ddx(1.0f);
+  if (continue_execution) {
+    output.Store(0u, asuint(v));
+  }
 }
 
 void main() {
diff --git a/test/tint/statements/discard/multiple_returns.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/discard/multiple_returns.wgsl.expected.ir.dxc.hlsl
index d5d5ab4..5f19b59 100644
--- a/test/tint/statements/discard/multiple_returns.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/discard/multiple_returns.wgsl.expected.ir.dxc.hlsl
@@ -6,14 +6,20 @@
   if ((asint(non_uniform_global.Load(0u)) < int(0))) {
     continue_execution = false;
   }
-  output.Store(0u, asuint(ddx(1.0f)));
+  float v = ddx(1.0f);
+  if (continue_execution) {
+    output.Store(0u, asuint(v));
+  }
   if ((asfloat(output.Load(0u)) < 0.0f)) {
     int i = int(0);
     {
       while(true) {
-        float v = asfloat(output.Load(0u));
-        if ((v > float(i))) {
-          output.Store(0u, asuint(float(i)));
+        float v_1 = asfloat(output.Load(0u));
+        if ((v_1 > float(i))) {
+          float v_2 = float(i);
+          if (continue_execution) {
+            output.Store(0u, asuint(v_2));
+          }
           if (!(continue_execution)) {
             discard;
           }
diff --git a/test/tint/statements/discard/multiple_returns.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/discard/multiple_returns.wgsl.expected.ir.fxc.hlsl
index d5d5ab4..5f19b59 100644
--- a/test/tint/statements/discard/multiple_returns.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/discard/multiple_returns.wgsl.expected.ir.fxc.hlsl
@@ -6,14 +6,20 @@
   if ((asint(non_uniform_global.Load(0u)) < int(0))) {
     continue_execution = false;
   }
-  output.Store(0u, asuint(ddx(1.0f)));
+  float v = ddx(1.0f);
+  if (continue_execution) {
+    output.Store(0u, asuint(v));
+  }
   if ((asfloat(output.Load(0u)) < 0.0f)) {
     int i = int(0);
     {
       while(true) {
-        float v = asfloat(output.Load(0u));
-        if ((v > float(i))) {
-          output.Store(0u, asuint(float(i)));
+        float v_1 = asfloat(output.Load(0u));
+        if ((v_1 > float(i))) {
+          float v_2 = float(i);
+          if (continue_execution) {
+            output.Store(0u, asuint(v_2));
+          }
           if (!(continue_execution)) {
             discard;
           }
diff --git a/test/tint/statements/discard/non_uniform.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/discard/non_uniform.wgsl.expected.ir.dxc.hlsl
index 15986f38e..54fd04a 100644
--- a/test/tint/statements/discard/non_uniform.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/discard/non_uniform.wgsl.expected.ir.dxc.hlsl
@@ -6,7 +6,10 @@
   if ((asint(non_uniform_global.Load(0u)) < int(0))) {
     continue_execution = false;
   }
-  output.Store(0u, asuint(ddx(1.0f)));
+  float v = ddx(1.0f);
+  if (continue_execution) {
+    output.Store(0u, asuint(v));
+  }
   if (!(continue_execution)) {
     discard;
   }
diff --git a/test/tint/statements/discard/non_uniform.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/discard/non_uniform.wgsl.expected.ir.fxc.hlsl
index 15986f38e..54fd04a 100644
--- a/test/tint/statements/discard/non_uniform.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/discard/non_uniform.wgsl.expected.ir.fxc.hlsl
@@ -6,7 +6,10 @@
   if ((asint(non_uniform_global.Load(0u)) < int(0))) {
     continue_execution = false;
   }
-  output.Store(0u, asuint(ddx(1.0f)));
+  float v = ddx(1.0f);
+  if (continue_execution) {
+    output.Store(0u, asuint(v));
+  }
   if (!(continue_execution)) {
     discard;
   }