[ir] Emit unused side-effecting expressions

When function calls are used by instructions that are themselves
unused, we were dropping the whole expression chain and never emitting
the function call at all.

Fix this in `ValueToLet` by making sure that all unused expressions
with side effects are associated with an instruction that will become
a statement (either a `call` or a `let`).

Fixed: 342650077
Fixed: 347690530
Fixed: 356419165
Change-Id: Ib78e31a4c32ddc02aa818316b00078ff80d961f8
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/205116
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/ir/transform/value_to_let.cc b/src/tint/lang/core/ir/transform/value_to_let.cc
index 630dd32..9537cef 100644
--- a/src/tint/lang/core/ir/transform/value_to_let.cc
+++ b/src/tint/lang/core/ir/transform/value_to_let.cc
@@ -90,11 +90,22 @@
             pending_resolution.Clear();
         };
 
-        auto maybe_put_in_let = [&](auto* inst) {
+        auto maybe_put_in_let = [&](auto* inst, Accesses& accesses) {
             if (auto* result = inst->Result(0)) {
                 auto& usages = result->UsagesUnsorted();
                 switch (result->NumUsages()) {
                     case 0:  // No usage
+                        if (accesses.Contains(Access::kStore)) {
+                            // This instruction needs to be emitted but has no uses, so we need to
+                            // make sure that it will be used in a statement. Function call
+                            // instructions with no uses will be emitted as call statements, so we
+                            // just need to put other instructions in `let`s to force them to be
+                            // emitted.
+                            if (!inst->template IsAnyOf<core::ir::Call>() ||
+                                inst->template IsAnyOf<core::ir::Construct, core::ir::Convert>()) {
+                                inst = PutInLet(result);
+                            }
+                        }
                         break;
                     case 1: {  // Single usage
                         auto usage = (*usages.begin())->instruction;
@@ -142,13 +153,13 @@
             if (accesses.Contains(Access::kStore)) {  // Note: Also handles load + store
                 put_pending_in_lets();
                 pending_access = Access::kStore;
-                maybe_put_in_let(inst);
+                maybe_put_in_let(inst, accesses);
             } else if (accesses.Contains(Access::kLoad)) {
                 if (pending_access != Access::kLoad) {
                     put_pending_in_lets();
                     pending_access = Access::kLoad;
                 }
-                maybe_put_in_let(inst);
+                maybe_put_in_let(inst, accesses);
             }
         }
     }
diff --git a/src/tint/lang/core/ir/transform/value_to_let_test.cc b/src/tint/lang/core/ir/transform/value_to_let_test.cc
index d88039e..47c0e2f 100644
--- a/src/tint/lang/core/ir/transform/value_to_let_test.cc
+++ b/src/tint/lang/core/ir/transform/value_to_let_test.cc
@@ -506,6 +506,198 @@
     EXPECT_EQ(str(), expect);
 }
 
+TEST_F(IR_ValueToLetTest, Call_WithUseThatIsNeverUsed) {
+    auto* v = b.Var<private_, i32>("v");
+    mod.root_block->Append(v);
+
+    auto* foo = b.Function("foo", ty.i32());
+    b.Append(foo->Block(), [&] {
+        b.Store(v, 42_i);
+        b.Return(foo, 1_i);
+    });
+
+    auto* fn = b.Function("F", ty.void_());
+    b.Append(fn->Block(), [&] {
+        auto* c = b.Name("call", b.Call<i32>(foo));
+        b.Name("add", b.Add<i32>(c, 1_i));
+        b.Return(fn);
+    });
+
+    auto* src = R"(
+$B1: {  # root
+  %v:ptr<private, i32, read_write> = var
+}
+
+%foo = func():i32 {
+  $B2: {
+    store %v, 42i
+    ret 1i
+  }
+}
+%F = func():void {
+  $B3: {
+    %call:i32 = call %foo
+    %add:i32 = add %call, 1i
+    ret
+  }
+}
+)";
+    EXPECT_EQ(str(), src);
+
+    auto* expect = R"(
+$B1: {  # root
+  %v:ptr<private, i32, read_write> = var
+}
+
+%foo = func():i32 {
+  $B2: {
+    store %v, 42i
+    ret 1i
+  }
+}
+%F = func():void {
+  $B3: {
+    %call:i32 = call %foo
+    %5:i32 = add %call, 1i
+    %add:i32 = let %5
+    ret
+  }
+}
+)";
+
+    Run(ValueToLet);
+
+    EXPECT_EQ(str(), expect);
+}
+
+TEST_F(IR_ValueToLetTest, ConstructIsNeverUsed) {
+    auto* v = b.Var<private_, i32>("v");
+    mod.root_block->Append(v);
+
+    auto* foo = b.Function("foo", ty.i32());
+    b.Append(foo->Block(), [&] {
+        b.Store(v, 42_i);
+        b.Return(foo, 1_i);
+    });
+
+    auto* fn = b.Function("F", ty.void_());
+    b.Append(fn->Block(), [&] {
+        auto* c = b.Name("call", b.Call<i32>(foo));
+        b.Name("construct", b.Construct<vec4<i32>>(c));
+        b.Return(fn);
+    });
+
+    auto* src = R"(
+$B1: {  # root
+  %v:ptr<private, i32, read_write> = var
+}
+
+%foo = func():i32 {
+  $B2: {
+    store %v, 42i
+    ret 1i
+  }
+}
+%F = func():void {
+  $B3: {
+    %call:i32 = call %foo
+    %construct:vec4<i32> = construct %call
+    ret
+  }
+}
+)";
+    EXPECT_EQ(str(), src);
+
+    auto* expect = R"(
+$B1: {  # root
+  %v:ptr<private, i32, read_write> = var
+}
+
+%foo = func():i32 {
+  $B2: {
+    store %v, 42i
+    ret 1i
+  }
+}
+%F = func():void {
+  $B3: {
+    %call:i32 = call %foo
+    %5:vec4<i32> = construct %call
+    %construct:vec4<i32> = let %5
+    ret
+  }
+}
+)";
+
+    Run(ValueToLet);
+
+    EXPECT_EQ(str(), expect);
+}
+
+TEST_F(IR_ValueToLetTest, ConvertIsNeverUsed) {
+    auto* v = b.Var<private_, i32>("v");
+    mod.root_block->Append(v);
+
+    auto* foo = b.Function("foo", ty.i32());
+    b.Append(foo->Block(), [&] {
+        b.Store(v, 42_i);
+        b.Return(foo, 1_i);
+    });
+
+    auto* fn = b.Function("F", ty.void_());
+    b.Append(fn->Block(), [&] {
+        auto* c = b.Name("call", b.Call<i32>(foo));
+        b.Name("convert", b.Convert<u32>(c));
+        b.Return(fn);
+    });
+
+    auto* src = R"(
+$B1: {  # root
+  %v:ptr<private, i32, read_write> = var
+}
+
+%foo = func():i32 {
+  $B2: {
+    store %v, 42i
+    ret 1i
+  }
+}
+%F = func():void {
+  $B3: {
+    %call:i32 = call %foo
+    %convert:u32 = convert %call
+    ret
+  }
+}
+)";
+    EXPECT_EQ(str(), src);
+
+    auto* expect = R"(
+$B1: {  # root
+  %v:ptr<private, i32, read_write> = var
+}
+
+%foo = func():i32 {
+  $B2: {
+    store %v, 42i
+    ret 1i
+  }
+}
+%F = func():void {
+  $B3: {
+    %call:i32 = call %foo
+    %5:u32 = convert %call
+    %convert:u32 = let %5
+    ret
+  }
+}
+)";
+
+    Run(ValueToLet);
+
+    EXPECT_EQ(str(), expect);
+}
+
 TEST_F(IR_ValueToLetTest, TwoCalls_ThenUseReturnValues) {
     auto* i = b.Var<private_, i32>("i");
     b.ir.root_block->Append(i);
diff --git a/test/tint/bug/chromium/1273230.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/chromium/1273230.wgsl.expected.ir.dxc.hlsl
index 1be29d6..8f0e56b 100644
--- a/test/tint/bug/chromium/1273230.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/chromium/1273230.wgsl.expected.ir.dxc.hlsl
@@ -97,9 +97,10 @@
   float3 center = (((p0 + p2) + p1) / 3.0f);
   float3 voxelPos = toVoxelPos(p1);
   uint lIndex = toIndex1D(uniforms[0u].y, p0);
-  int v_16 = 0;
-  LUT.InterlockedAdd(int(0u), 1, v_16);
-  int triangleOffset = v_16;
+  uint v_16 = (uint(i1) * 4u);
+  int v_17 = 0;
+  LUT.InterlockedAdd(int(0u), 1, v_17);
+  int triangleOffset = v_17;
 }
 
 [numthreads(128, 1, 1)]
diff --git a/test/tint/bug/chromium/1273230.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/chromium/1273230.wgsl.expected.ir.fxc.hlsl
index 1be29d6..8f0e56b 100644
--- a/test/tint/bug/chromium/1273230.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/chromium/1273230.wgsl.expected.ir.fxc.hlsl
@@ -97,9 +97,10 @@
   float3 center = (((p0 + p2) + p1) / 3.0f);
   float3 voxelPos = toVoxelPos(p1);
   uint lIndex = toIndex1D(uniforms[0u].y, p0);
-  int v_16 = 0;
-  LUT.InterlockedAdd(int(0u), 1, v_16);
-  int triangleOffset = v_16;
+  uint v_16 = (uint(i1) * 4u);
+  int v_17 = 0;
+  LUT.InterlockedAdd(int(0u), 1, v_17);
+  int triangleOffset = v_17;
 }
 
 [numthreads(128, 1, 1)]
diff --git a/test/tint/bug/chromium/1405676.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/chromium/1405676.wgsl.expected.ir.dxc.hlsl
index 3d7ef42..1e55309 100644
--- a/test/tint/bug/chromium/1405676.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/chromium/1405676.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,7 @@
 void d() {
   Texture1D<int4> v = arg_0;
   int v_1 = int(1);
-  int4(v.Load(int2(v_1, int(0))));
+  int4 v_2 = int4(v.Load(int2(v_1, int(0))));
   float l = 0.14112000167369842529f;
 }
 
diff --git a/test/tint/bug/chromium/1405676.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/chromium/1405676.wgsl.expected.ir.fxc.hlsl
index 3d7ef42..1e55309 100644
--- a/test/tint/bug/chromium/1405676.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/chromium/1405676.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,7 @@
 void d() {
   Texture1D<int4> v = arg_0;
   int v_1 = int(1);
-  int4(v.Load(int2(v_1, int(0))));
+  int4 v_2 = int4(v.Load(int2(v_1, int(0))));
   float l = 0.14112000167369842529f;
 }
 
diff --git a/test/tint/bug/chromium/335592006.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/chromium/335592006.wgsl.expected.ir.dxc.hlsl
index 97f6830..ba0068d 100644
--- a/test/tint/bug/chromium/335592006.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/chromium/335592006.wgsl.expected.ir.dxc.hlsl
@@ -3,20 +3,10 @@
 
 void f() {
   int a = 1;
-  int(a);
+  int v = int(a);
 }
 
 [numthreads(1, 1, 1)]
 void unused_entry_point() {
 }
 
-DXC validation failure:
-hlsl.hlsl:4:7: error: redefinition of 'a'
-  int(a);
-      ^
-hlsl.hlsl:3:7: note: previous definition is here
-  int a = 1;
-      ^
-
-
-tint executable returned error: exit status 1
diff --git a/test/tint/bug/chromium/335592006.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/chromium/335592006.wgsl.expected.ir.fxc.hlsl
index 5a1fe59..f96dc35 100644
--- a/test/tint/bug/chromium/335592006.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/chromium/335592006.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,7 @@
 
 void f() {
   int a = 1;
-  int(a);
+  int v = int(a);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/chromium/335592006.wgsl.expected.ir.glsl b/test/tint/bug/chromium/335592006.wgsl.expected.ir.glsl
index dfd7adb..8000cd6 100644
--- a/test/tint/bug/chromium/335592006.wgsl.expected.ir.glsl
+++ b/test/tint/bug/chromium/335592006.wgsl.expected.ir.glsl
@@ -2,7 +2,7 @@
 
 void f() {
   int a = 1;
-  int(a);
+  int v = int(a);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/chromium/335592006.wgsl.expected.ir.msl b/test/tint/bug/chromium/335592006.wgsl.expected.ir.msl
index 5a5a617..8beddca 100644
--- a/test/tint/bug/chromium/335592006.wgsl.expected.ir.msl
+++ b/test/tint/bug/chromium/335592006.wgsl.expected.ir.msl
@@ -1,16 +1,7 @@
-SKIP: FAILED
-
 #include <metal_stdlib>
 using namespace metal;
 
 void f() {
   int const a = 1;
-  int(a);
+  int const v = int(a);
 }
-program_source:6:7: error: redefinition of 'a' with a different type: 'int' vs 'const int'
-  int(a);
-      ^
-program_source:5:13: note: previous definition is here
-  int const a = 1;
-            ^
-
diff --git a/test/tint/bug/tint/1113.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/1113.wgsl.expected.ir.dxc.hlsl
index 842bec9..7a12bd9 100644
--- a/test/tint/bug/tint/1113.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/1113.wgsl.expected.ir.dxc.hlsl
@@ -102,9 +102,10 @@
   float3 center = (((p0 + p1) + p2) / 3.0f);
   float3 voxelPos = toVoxelPos(center);
   uint voxelIndex = toIndex1D(uniforms[0u].y, voxelPos);
-  uint v_16 = 0u;
-  counters.InterlockedAdd(uint(0u), 1u, v_16);
-  uint acefg = v_16;
+  uint v_16 = (uint(voxelIndex) * 4u);
+  uint v_17 = 0u;
+  counters.InterlockedAdd(uint(0u), 1u, v_17);
+  uint acefg = v_17;
   if ((triangleIndex == 0u)) {
     dbg.Store(16u, uniforms[0u].y);
     dbg.Store(32u, asuint(center.x));
@@ -120,19 +121,21 @@
   if ((voxelIndex >= maxVoxels)) {
     return;
   }
-  uint v_17 = 0u;
-  counters.InterlockedOr(uint(0u), 0u, v_17);
-  uint numTriangles = v_17;
+  uint v_18 = (uint(voxelIndex) * 4u);
+  uint v_19 = 0u;
+  counters.InterlockedOr(uint(0u), 0u, v_19);
+  uint numTriangles = v_19;
   int offset = -1;
   if ((numTriangles > 0u)) {
-    uint v_18 = numTriangles;
-    uint v_19 = 0u;
-    dbg.InterlockedAdd(uint(0u), v_18, v_19);
-    offset = int(v_19);
+    uint v_20 = numTriangles;
+    uint v_21 = 0u;
+    dbg.InterlockedAdd(uint(0u), v_20, v_21);
+    offset = int(v_21);
   }
-  int v_20 = offset;
-  int v_21 = 0;
-  LUT.InterlockedExchange(int(0u), v_20, v_21);
+  uint v_22 = (uint(voxelIndex) * 4u);
+  int v_23 = offset;
+  int v_24 = 0;
+  LUT.InterlockedExchange(int(0u), v_23, v_24);
 }
 
 void main_sort_triangles_inner(uint3 GlobalInvocationID) {
@@ -150,9 +153,10 @@
   float3 center = (((p0 + p1) + p2) / 3.0f);
   float3 voxelPos = toVoxelPos(center);
   uint voxelIndex = toIndex1D(uniforms[0u].y, voxelPos);
-  int v_22 = 0;
-  LUT.InterlockedAdd(int(0u), 1, v_22);
-  int triangleOffset = v_22;
+  uint v_25 = (uint(voxelIndex) * 4u);
+  int v_26 = 0;
+  LUT.InterlockedAdd(int(0u), 1, v_26);
+  int triangleOffset = v_26;
 }
 
 [numthreads(128, 1, 1)]
diff --git a/test/tint/bug/tint/1113.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/1113.wgsl.expected.ir.fxc.hlsl
index 842bec9..7a12bd9 100644
--- a/test/tint/bug/tint/1113.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/1113.wgsl.expected.ir.fxc.hlsl
@@ -102,9 +102,10 @@
   float3 center = (((p0 + p1) + p2) / 3.0f);
   float3 voxelPos = toVoxelPos(center);
   uint voxelIndex = toIndex1D(uniforms[0u].y, voxelPos);
-  uint v_16 = 0u;
-  counters.InterlockedAdd(uint(0u), 1u, v_16);
-  uint acefg = v_16;
+  uint v_16 = (uint(voxelIndex) * 4u);
+  uint v_17 = 0u;
+  counters.InterlockedAdd(uint(0u), 1u, v_17);
+  uint acefg = v_17;
   if ((triangleIndex == 0u)) {
     dbg.Store(16u, uniforms[0u].y);
     dbg.Store(32u, asuint(center.x));
@@ -120,19 +121,21 @@
   if ((voxelIndex >= maxVoxels)) {
     return;
   }
-  uint v_17 = 0u;
-  counters.InterlockedOr(uint(0u), 0u, v_17);
-  uint numTriangles = v_17;
+  uint v_18 = (uint(voxelIndex) * 4u);
+  uint v_19 = 0u;
+  counters.InterlockedOr(uint(0u), 0u, v_19);
+  uint numTriangles = v_19;
   int offset = -1;
   if ((numTriangles > 0u)) {
-    uint v_18 = numTriangles;
-    uint v_19 = 0u;
-    dbg.InterlockedAdd(uint(0u), v_18, v_19);
-    offset = int(v_19);
+    uint v_20 = numTriangles;
+    uint v_21 = 0u;
+    dbg.InterlockedAdd(uint(0u), v_20, v_21);
+    offset = int(v_21);
   }
-  int v_20 = offset;
-  int v_21 = 0;
-  LUT.InterlockedExchange(int(0u), v_20, v_21);
+  uint v_22 = (uint(voxelIndex) * 4u);
+  int v_23 = offset;
+  int v_24 = 0;
+  LUT.InterlockedExchange(int(0u), v_23, v_24);
 }
 
 void main_sort_triangles_inner(uint3 GlobalInvocationID) {
@@ -150,9 +153,10 @@
   float3 center = (((p0 + p1) + p2) / 3.0f);
   float3 voxelPos = toVoxelPos(center);
   uint voxelIndex = toIndex1D(uniforms[0u].y, voxelPos);
-  int v_22 = 0;
-  LUT.InterlockedAdd(int(0u), 1, v_22);
-  int triangleOffset = v_22;
+  uint v_25 = (uint(voxelIndex) * 4u);
+  int v_26 = 0;
+  LUT.InterlockedAdd(int(0u), 1, v_26);
+  int triangleOffset = v_26;
 }
 
 [numthreads(128, 1, 1)]
diff --git a/test/tint/bug/tint/1121.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/1121.wgsl.expected.ir.dxc.hlsl
index c31958a..893d244 100644
--- a/test/tint/bug/tint/1121.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/1121.wgsl.expected.ir.dxc.hlsl
@@ -123,18 +123,19 @@
               }
               continue;
             }
-            uint v_17 = 0u;
-            tileLightId.InterlockedAdd(uint(0u), 1u, v_17);
-            uint offset = v_17;
+            uint v_17 = (uint(tileId) * 260u);
+            uint v_18 = 0u;
+            tileLightId.InterlockedAdd(uint(0u), 1u, v_18);
+            uint offset = v_18;
             if ((offset >= config[1u].x)) {
               {
                 x = (x + 1);
               }
               continue;
             }
-            uint v_18 = offset;
-            uint v_19 = (uint(tileId) * 260u);
-            tileLightId.Store(((4u + v_19) + (uint(v_18) * 4u)), GlobalInvocationID[0u]);
+            uint v_19 = offset;
+            uint v_20 = (uint(tileId) * 260u);
+            tileLightId.Store(((4u + v_20) + (uint(v_19) * 4u)), GlobalInvocationID[0u]);
           }
           {
             x = (x + 1);
diff --git a/test/tint/bug/tint/1121.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/1121.wgsl.expected.ir.fxc.hlsl
index c31958a..893d244 100644
--- a/test/tint/bug/tint/1121.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/1121.wgsl.expected.ir.fxc.hlsl
@@ -123,18 +123,19 @@
               }
               continue;
             }
-            uint v_17 = 0u;
-            tileLightId.InterlockedAdd(uint(0u), 1u, v_17);
-            uint offset = v_17;
+            uint v_17 = (uint(tileId) * 260u);
+            uint v_18 = 0u;
+            tileLightId.InterlockedAdd(uint(0u), 1u, v_18);
+            uint offset = v_18;
             if ((offset >= config[1u].x)) {
               {
                 x = (x + 1);
               }
               continue;
             }
-            uint v_18 = offset;
-            uint v_19 = (uint(tileId) * 260u);
-            tileLightId.Store(((4u + v_19) + (uint(v_18) * 4u)), GlobalInvocationID[0u]);
+            uint v_19 = offset;
+            uint v_20 = (uint(tileId) * 260u);
+            tileLightId.Store(((4u + v_20) + (uint(v_19) * 4u)), GlobalInvocationID[0u]);
           }
           {
             x = (x + 1);
diff --git a/test/tint/bug/tint/993.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/993.wgsl.expected.ir.dxc.hlsl
index e875379..221d080 100644
--- a/test/tint/bug/tint/993.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/993.wgsl.expected.ir.dxc.hlsl
@@ -5,9 +5,10 @@
 RWByteAddressBuffer result : register(u1, space1);
 RWByteAddressBuffer s : register(u0);
 int runTest() {
-  int v = 0;
-  s.InterlockedOr(int(0u), 0, v);
-  return v;
+  uint v = (uint((0u + uint(constants[0u].x))) * 4u);
+  int v_1 = 0;
+  s.InterlockedOr(int(0u), 0, v_1);
+  return v_1;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/993.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/993.wgsl.expected.ir.fxc.hlsl
index e875379..221d080 100644
--- a/test/tint/bug/tint/993.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/993.wgsl.expected.ir.fxc.hlsl
@@ -5,9 +5,10 @@
 RWByteAddressBuffer result : register(u1, space1);
 RWByteAddressBuffer s : register(u0);
 int runTest() {
-  int v = 0;
-  s.InterlockedOr(int(0u), 0, v);
-  return v;
+  uint v = (uint((0u + uint(constants[0u].x))) * 4u);
+  int v_1 = 0;
+  s.InterlockedOr(int(0u), 0, v_1);
+  return v_1;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/statements/assign/phony/multiple_side_effects.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/phony/multiple_side_effects.wgsl.expected.ir.dxc.hlsl
index efead7a..99ccef4 100644
--- a/test/tint/statements/assign/phony/multiple_side_effects.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/phony/multiple_side_effects.wgsl.expected.ir.dxc.hlsl
@@ -7,5 +7,6 @@
 void main() {
   int v = f(1, 2, 3);
   int v_1 = f(4, 5, 6);
+  int v_2 = (v + (v_1 * f(7, f(8, 9, 10), 11)));
 }
 
diff --git a/test/tint/statements/assign/phony/multiple_side_effects.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/assign/phony/multiple_side_effects.wgsl.expected.ir.fxc.hlsl
index efead7a..99ccef4 100644
--- a/test/tint/statements/assign/phony/multiple_side_effects.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/assign/phony/multiple_side_effects.wgsl.expected.ir.fxc.hlsl
@@ -7,5 +7,6 @@
 void main() {
   int v = f(1, 2, 3);
   int v_1 = f(4, 5, 6);
+  int v_2 = (v + (v_1 * f(7, f(8, 9, 10), 11)));
 }
 
diff --git a/test/tint/statements/assign/phony/multiple_side_effects.wgsl.expected.ir.glsl b/test/tint/statements/assign/phony/multiple_side_effects.wgsl.expected.ir.glsl
index 0881599..0a272b1 100644
--- a/test/tint/statements/assign/phony/multiple_side_effects.wgsl.expected.ir.glsl
+++ b/test/tint/statements/assign/phony/multiple_side_effects.wgsl.expected.ir.glsl
@@ -7,4 +7,5 @@
 void main() {
   int v = f(1, 2, 3);
   int v_1 = f(4, 5, 6);
+  int v_2 = (v + (v_1 * f(7, f(8, 9, 10), 11)));
 }
diff --git a/test/tint/statements/assign/phony/multiple_side_effects.wgsl.expected.ir.msl b/test/tint/statements/assign/phony/multiple_side_effects.wgsl.expected.ir.msl
index 50f4c9f..94223e3 100644
--- a/test/tint/statements/assign/phony/multiple_side_effects.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/phony/multiple_side_effects.wgsl.expected.ir.msl
@@ -8,4 +8,5 @@
 kernel void tint_symbol() {
   int const v = f(1, 2, 3);
   int const v_1 = f(4, 5, 6);
+  int const v_2 = (v + (v_1 * f(7, f(8, 9, 10), 11)));
 }