spirv-reader: specop support Select

The translation only supports OpSpecConstantOp with a scalar result type.
ICE in the case of a vector result type.

Fixed: 402727458
Change-Id: I0e7db48831c9a63a2bf4575a78cf3cbb2bcfa784
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/250674
Commit-Queue: David Neto <dneto@google.com>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/spirv/reader/parser/parser.cc b/src/tint/lang/spirv/reader/parser/parser.cc
index 72d475b..d0a49af 100644
--- a/src/tint/lang/spirv/reader/parser/parser.cc
+++ b/src/tint/lang/spirv/reader/parser/parser.cc
@@ -462,6 +462,16 @@
                             TINT_ICE() << "can't translate OpSpecConstantOp with VectorShuffle: "
                                           "OpSpecConstantOp maps to a WGSL override declaration, "
                                           "but WGSL overrides must have scalar type";
+                        case spv::Op::OpSelect:
+                            if (!Type(inst.type_id())->IsScalar()) {
+                                TINT_ICE()
+                                    << "can't translate OpSpecConstantOp with Select that returns "
+                                       "a vector: "
+                                       "OpSpecConstantOp maps to a WGSL override declaration, "
+                                       "but WGSL overrides must have scalar type";
+                            }
+                            EmitSpirvBuiltinCall(inst, spirv::BuiltinFn::kSelect, 3);
+                            break;
                         default:
                             TINT_ICE() << "Unknown spec constant operation: " << op;
                     }
diff --git a/src/tint/lang/spirv/reader/parser/var_test.cc b/src/tint/lang/spirv/reader/parser/var_test.cc
index e47a1f7..63ab072 100644
--- a/src/tint/lang/spirv/reader/parser/var_test.cc
+++ b/src/tint/lang/spirv/reader/parser/var_test.cc
@@ -2802,6 +2802,47 @@
 )");
 }
 
+TEST_F(SpirvParserTest, Var_OpSpecConstantOp_Select_CondScalar_ArgsScalar) {
+    // In SPIR-V the arg types must be the same as the result type.
+    // WGSL only supports overrides with scalar type, so only test the
+    // case where the result type is scalar.
+    EXPECT_IR(R"(
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %main "main"
+               OpExecutionMode %main LocalSize 1 1 1
+               OpName %myconst "myconst"
+       %void = OpTypeVoid
+       %bool = OpTypeBool
+        %u32 = OpTypeInt 32 0
+        %i32 = OpTypeInt 32 1
+       %true = OpConstantTrue %bool
+      %false = OpConstantFalse %bool
+        %one = OpConstant %i32 1
+        %two = OpConstant %i32 2
+    %myconst = OpSpecConstantOp %i32 Select %true %one %two
+     %voidfn = OpTypeFunction %void
+       %main = OpFunction %void None %voidfn
+ %main_entry = OpLabel
+          %1 = OpCopyObject %i32 %myconst
+               OpReturn
+               OpFunctionEnd
+)",
+              R"(
+$B1: {  # root
+  %1:i32 = spirv.select true, 1i, 2i
+  %myconst:i32 = override %1
+}
+
+%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
+  $B2: {
+    %4:i32 = let %myconst
+    ret
+  }
+}
+)");
+}
+
 // In the case of all literals, SPIR-V opt treats the `OpSpecConstantComposite` as an
 // `OpConstantComposite` so it appears in the constant manager already. This then needs no handling
 // on our side.