[tint][ir] Don't emit instructions with abstract types.

Bug: chromium:324466107
Change-Id: I904d3614e0fe01a7b49c45bfd96463f686b77c4a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/174580
Auto-Submit: Ben Clayton <bclayton@google.com>
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: David Neto <dneto@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
index 05505d1..6d4621a 100644
--- a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
+++ b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
@@ -450,13 +450,24 @@
     }
 
     void EmitAssignment(const ast::AssignmentStatement* stmt) {
-        // If assigning to a phony, just generate the RHS and we're done. Note that, because
-        // this isn't used, a subsequent transform could remove it due to it being dead code.
-        // This could then change the interface for the program (i.e. a global var no longer
-        // used). If that happens we have to either fix this to store to a phony value, or make
-        // sure we pull the interface before doing the dead code elimination.
+        // If assigning to a phony, and the expression evaluation stage is runtime or override, just
+        // generate the RHS and we're done. Note that, because this isn't used, a subsequent
+        // transform could remove it due to it being dead code. This could then change the interface
+        // for the program (i.e. a global var no longer used). If that happens we have to either fix
+        // this to store to a phony value, or make sure we pull the interface before doing the dead
+        // code elimination.
         if (stmt->lhs->Is<ast::PhonyExpression>()) {
-            (void)EmitValueExpression(stmt->rhs);
+            const auto* sem = program_.Sem().GetVal(stmt->rhs);
+            switch (sem->Stage()) {
+                case core::EvaluationStage::kRuntime:
+                case core::EvaluationStage::kOverride:
+                    EmitValueExpression(stmt->rhs);
+                    break;
+                case core::EvaluationStage::kNotEvaluated:
+                case core::EvaluationStage::kConstant:
+                    // Don't emit.
+                    break;
+            }
             return;
         }
 
diff --git a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir_test.cc b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir_test.cc
index b47ee3a..9867cb4 100644
--- a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir_test.cc
+++ b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir_test.cc
@@ -26,6 +26,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "gmock/gmock.h"
+#include "src/tint/lang/core/builtin_fn.h"
 #include "src/tint/lang/core/constant/scalar.h"
 #include "src/tint/lang/core/fluent_types.h"
 #include "src/tint/lang/core/ir/block.h"
@@ -1164,5 +1165,27 @@
 )");
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// Bugs
+////////////////////////////////////////////////////////////////////////////////
+TEST_F(IR_FromProgramTest, BugChromium324466107) {
+    Func("f", Empty, ty.void_(),
+         Vector{
+             // Abstract type on the RHS - cannot be emitted.
+             Assign(Phony(), Call(core::BuiltinFn::kFrexp, Call(ty.vec2<Infer>(), 2.0_a))),
+         });
+
+    auto m = Build();
+    ASSERT_EQ(m, Success);
+
+    EXPECT_EQ(Disassemble(m.Get()),
+              R"(%f = func():void -> %b1 {
+  %b1 = block {
+    ret
+  }
+}
+)");
+}
+
 }  // namespace
 }  // namespace tint::wgsl::reader
diff --git a/test/tint/bug/chromium/324466107.wgsl b/test/tint/bug/chromium/324466107.wgsl
new file mode 100644
index 0000000..52034f5
--- /dev/null
+++ b/test/tint/bug/chromium/324466107.wgsl
@@ -0,0 +1,3 @@
+fn f( ) {
+    _ = frexp(vec2(2.));
+}
diff --git a/test/tint/bug/chromium/324466107.wgsl.expected.dxc.hlsl b/test/tint/bug/chromium/324466107.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..7412e64
--- /dev/null
+++ b/test/tint/bug/chromium/324466107.wgsl.expected.dxc.hlsl
@@ -0,0 +1,7 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+  return;
+}
+
+void f() {
+}
diff --git a/test/tint/bug/chromium/324466107.wgsl.expected.fxc.hlsl b/test/tint/bug/chromium/324466107.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..7412e64
--- /dev/null
+++ b/test/tint/bug/chromium/324466107.wgsl.expected.fxc.hlsl
@@ -0,0 +1,7 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+  return;
+}
+
+void f() {
+}
diff --git a/test/tint/bug/chromium/324466107.wgsl.expected.glsl b/test/tint/bug/chromium/324466107.wgsl.expected.glsl
new file mode 100644
index 0000000..45d48f9
--- /dev/null
+++ b/test/tint/bug/chromium/324466107.wgsl.expected.glsl
@@ -0,0 +1,9 @@
+#version 310 es
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void unused_entry_point() {
+  return;
+}
+void f() {
+}
+
diff --git a/test/tint/bug/chromium/324466107.wgsl.expected.msl b/test/tint/bug/chromium/324466107.wgsl.expected.msl
new file mode 100644
index 0000000..7e5829a
--- /dev/null
+++ b/test/tint/bug/chromium/324466107.wgsl.expected.msl
@@ -0,0 +1,6 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void f() {
+}
+
diff --git a/test/tint/bug/chromium/324466107.wgsl.expected.spvasm b/test/tint/bug/chromium/324466107.wgsl.expected.spvasm
new file mode 100644
index 0000000..1c4d684
--- /dev/null
+++ b/test/tint/bug/chromium/324466107.wgsl.expected.spvasm
@@ -0,0 +1,21 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 7
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+               OpExecutionMode %unused_entry_point LocalSize 1 1 1
+               OpName %unused_entry_point "unused_entry_point"
+               OpName %f "f"
+       %void = OpTypeVoid
+          %1 = OpTypeFunction %void
+%unused_entry_point = OpFunction %void None %1
+          %4 = OpLabel
+               OpReturn
+               OpFunctionEnd
+          %f = OpFunction %void None %1
+          %6 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/bug/chromium/324466107.wgsl.expected.wgsl b/test/tint/bug/chromium/324466107.wgsl.expected.wgsl
new file mode 100644
index 0000000..f0d449b
--- /dev/null
+++ b/test/tint/bug/chromium/324466107.wgsl.expected.wgsl
@@ -0,0 +1,3 @@
+fn f() {
+  _ = frexp(vec2(2.0));
+}