test: Add vector constructor tests

These test vector constructors with an explicit element type.

Bug: tint:1334
Change-Id: I3d0f626e42850e841cffd70241274e32dcb75fbb
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/72142
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/test/expressions/type_ctor/vec2/explicit/bool.wgsl b/test/expressions/type_ctor/vec2/explicit/bool.wgsl
new file mode 100644
index 0000000..c215909
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/bool.wgsl
@@ -0,0 +1 @@
+let v = vec2<bool>(false, true);
diff --git a/test/expressions/type_ctor/vec2/explicit/bool.wgsl.expected.hlsl b/test/expressions/type_ctor/vec2/explicit/bool.wgsl.expected.hlsl
new file mode 100644
index 0000000..0ba8ae6
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/bool.wgsl.expected.hlsl
@@ -0,0 +1,6 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+  return;
+}
+
+static const bool2 v = bool2(false, true);
diff --git a/test/expressions/type_ctor/vec2/explicit/bool.wgsl.expected.msl b/test/expressions/type_ctor/vec2/explicit/bool.wgsl.expected.msl
new file mode 100644
index 0000000..3103a85
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/bool.wgsl.expected.msl
@@ -0,0 +1,4 @@
+#include <metal_stdlib>
+
+using namespace metal;
+constant bool2 v = bool2(false, true);
diff --git a/test/expressions/type_ctor/vec2/explicit/bool.wgsl.expected.spvasm b/test/expressions/type_ctor/vec2/explicit/bool.wgsl.expected.spvasm
new file mode 100644
index 0000000..b982dbd
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/bool.wgsl.expected.spvasm
@@ -0,0 +1,22 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 10
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+               OpExecutionMode %unused_entry_point LocalSize 1 1 1
+               OpName %v "v"
+               OpName %unused_entry_point "unused_entry_point"
+       %bool = OpTypeBool
+     %v2bool = OpTypeVector %bool 2
+      %false = OpConstantFalse %bool
+       %true = OpConstantTrue %bool
+          %v = OpConstantComposite %v2bool %false %true
+       %void = OpTypeVoid
+          %6 = OpTypeFunction %void
+%unused_entry_point = OpFunction %void None %6
+          %9 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/test/expressions/type_ctor/vec2/explicit/bool.wgsl.expected.wgsl b/test/expressions/type_ctor/vec2/explicit/bool.wgsl.expected.wgsl
new file mode 100644
index 0000000..c215909
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/bool.wgsl.expected.wgsl
@@ -0,0 +1 @@
+let v = vec2<bool>(false, true);
diff --git a/test/expressions/type_ctor/vec2/explicit/f32.wgsl b/test/expressions/type_ctor/vec2/explicit/f32.wgsl
new file mode 100644
index 0000000..87b1055
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/f32.wgsl
@@ -0,0 +1 @@
+let v = vec2<f32>(0.0, 1.0);
diff --git a/test/expressions/type_ctor/vec2/explicit/f32.wgsl.expected.hlsl b/test/expressions/type_ctor/vec2/explicit/f32.wgsl.expected.hlsl
new file mode 100644
index 0000000..8802bbb
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/f32.wgsl.expected.hlsl
@@ -0,0 +1,6 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+  return;
+}
+
+static const float2 v = float2(0.0f, 1.0f);
diff --git a/test/expressions/type_ctor/vec2/explicit/f32.wgsl.expected.msl b/test/expressions/type_ctor/vec2/explicit/f32.wgsl.expected.msl
new file mode 100644
index 0000000..6e66829
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/f32.wgsl.expected.msl
@@ -0,0 +1,4 @@
+#include <metal_stdlib>
+
+using namespace metal;
+constant float2 v = float2(0.0f, 1.0f);
diff --git a/test/expressions/type_ctor/vec2/explicit/f32.wgsl.expected.spvasm b/test/expressions/type_ctor/vec2/explicit/f32.wgsl.expected.spvasm
new file mode 100644
index 0000000..d12bbf2
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/f32.wgsl.expected.spvasm
@@ -0,0 +1,22 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 10
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+               OpExecutionMode %unused_entry_point LocalSize 1 1 1
+               OpName %v "v"
+               OpName %unused_entry_point "unused_entry_point"
+      %float = OpTypeFloat 32
+    %v2float = OpTypeVector %float 2
+    %float_0 = OpConstant %float 0
+    %float_1 = OpConstant %float 1
+          %v = OpConstantComposite %v2float %float_0 %float_1
+       %void = OpTypeVoid
+          %6 = OpTypeFunction %void
+%unused_entry_point = OpFunction %void None %6
+          %9 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/test/expressions/type_ctor/vec2/explicit/f32.wgsl.expected.wgsl b/test/expressions/type_ctor/vec2/explicit/f32.wgsl.expected.wgsl
new file mode 100644
index 0000000..87b1055
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/f32.wgsl.expected.wgsl
@@ -0,0 +1 @@
+let v = vec2<f32>(0.0, 1.0);
diff --git a/test/expressions/type_ctor/vec2/explicit/i32.wgsl b/test/expressions/type_ctor/vec2/explicit/i32.wgsl
new file mode 100644
index 0000000..ee90f91
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/i32.wgsl
@@ -0,0 +1 @@
+let v = vec2<i32>(0, 1);
diff --git a/test/expressions/type_ctor/vec2/explicit/i32.wgsl.expected.hlsl b/test/expressions/type_ctor/vec2/explicit/i32.wgsl.expected.hlsl
new file mode 100644
index 0000000..afa632e
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/i32.wgsl.expected.hlsl
@@ -0,0 +1,6 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+  return;
+}
+
+static const int2 v = int2(0, 1);
diff --git a/test/expressions/type_ctor/vec2/explicit/i32.wgsl.expected.msl b/test/expressions/type_ctor/vec2/explicit/i32.wgsl.expected.msl
new file mode 100644
index 0000000..2a0fc8d
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/i32.wgsl.expected.msl
@@ -0,0 +1,4 @@
+#include <metal_stdlib>
+
+using namespace metal;
+constant int2 v = int2(0, 1);
diff --git a/test/expressions/type_ctor/vec2/explicit/i32.wgsl.expected.spvasm b/test/expressions/type_ctor/vec2/explicit/i32.wgsl.expected.spvasm
new file mode 100644
index 0000000..2e021f9
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/i32.wgsl.expected.spvasm
@@ -0,0 +1,22 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 10
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+               OpExecutionMode %unused_entry_point LocalSize 1 1 1
+               OpName %v "v"
+               OpName %unused_entry_point "unused_entry_point"
+        %int = OpTypeInt 32 1
+      %v2int = OpTypeVector %int 2
+      %int_0 = OpConstant %int 0
+      %int_1 = OpConstant %int 1
+          %v = OpConstantComposite %v2int %int_0 %int_1
+       %void = OpTypeVoid
+          %6 = OpTypeFunction %void
+%unused_entry_point = OpFunction %void None %6
+          %9 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/test/expressions/type_ctor/vec2/explicit/i32.wgsl.expected.wgsl b/test/expressions/type_ctor/vec2/explicit/i32.wgsl.expected.wgsl
new file mode 100644
index 0000000..ee90f91
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/i32.wgsl.expected.wgsl
@@ -0,0 +1 @@
+let v = vec2<i32>(0, 1);
diff --git a/test/expressions/type_ctor/vec2/explicit/u32.wgsl b/test/expressions/type_ctor/vec2/explicit/u32.wgsl
new file mode 100644
index 0000000..1b3006c
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/u32.wgsl
@@ -0,0 +1 @@
+let v = vec2<u32>(0u, 1u);
diff --git a/test/expressions/type_ctor/vec2/explicit/u32.wgsl.expected.hlsl b/test/expressions/type_ctor/vec2/explicit/u32.wgsl.expected.hlsl
new file mode 100644
index 0000000..c298713
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/u32.wgsl.expected.hlsl
@@ -0,0 +1,6 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+  return;
+}
+
+static const uint2 v = uint2(0u, 1u);
diff --git a/test/expressions/type_ctor/vec2/explicit/u32.wgsl.expected.msl b/test/expressions/type_ctor/vec2/explicit/u32.wgsl.expected.msl
new file mode 100644
index 0000000..132ee56
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/u32.wgsl.expected.msl
@@ -0,0 +1,4 @@
+#include <metal_stdlib>
+
+using namespace metal;
+constant uint2 v = uint2(0u, 1u);
diff --git a/test/expressions/type_ctor/vec2/explicit/u32.wgsl.expected.spvasm b/test/expressions/type_ctor/vec2/explicit/u32.wgsl.expected.spvasm
new file mode 100644
index 0000000..8c3ad8f
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/u32.wgsl.expected.spvasm
@@ -0,0 +1,22 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 10
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+               OpExecutionMode %unused_entry_point LocalSize 1 1 1
+               OpName %v "v"
+               OpName %unused_entry_point "unused_entry_point"
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
+          %v = OpConstantComposite %v2uint %uint_0 %uint_1
+       %void = OpTypeVoid
+          %6 = OpTypeFunction %void
+%unused_entry_point = OpFunction %void None %6
+          %9 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/test/expressions/type_ctor/vec2/explicit/u32.wgsl.expected.wgsl b/test/expressions/type_ctor/vec2/explicit/u32.wgsl.expected.wgsl
new file mode 100644
index 0000000..1b3006c
--- /dev/null
+++ b/test/expressions/type_ctor/vec2/explicit/u32.wgsl.expected.wgsl
@@ -0,0 +1 @@
+let v = vec2<u32>(0u, 1u);
diff --git a/test/expressions/type_ctor/vec3/explicit/bool.wgsl b/test/expressions/type_ctor/vec3/explicit/bool.wgsl
new file mode 100644
index 0000000..0acf3bf
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/bool.wgsl
@@ -0,0 +1 @@
+let v = vec3<bool>(false, true, false);
diff --git a/test/expressions/type_ctor/vec3/explicit/bool.wgsl.expected.hlsl b/test/expressions/type_ctor/vec3/explicit/bool.wgsl.expected.hlsl
new file mode 100644
index 0000000..d5acfa0
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/bool.wgsl.expected.hlsl
@@ -0,0 +1,6 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+  return;
+}
+
+static const bool3 v = bool3(false, true, false);
diff --git a/test/expressions/type_ctor/vec3/explicit/bool.wgsl.expected.msl b/test/expressions/type_ctor/vec3/explicit/bool.wgsl.expected.msl
new file mode 100644
index 0000000..5393cb3
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/bool.wgsl.expected.msl
@@ -0,0 +1,4 @@
+#include <metal_stdlib>
+
+using namespace metal;
+constant bool3 v = bool3(false, true, false);
diff --git a/test/expressions/type_ctor/vec3/explicit/bool.wgsl.expected.spvasm b/test/expressions/type_ctor/vec3/explicit/bool.wgsl.expected.spvasm
new file mode 100644
index 0000000..b712760
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/bool.wgsl.expected.spvasm
@@ -0,0 +1,22 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 10
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+               OpExecutionMode %unused_entry_point LocalSize 1 1 1
+               OpName %v "v"
+               OpName %unused_entry_point "unused_entry_point"
+       %bool = OpTypeBool
+     %v3bool = OpTypeVector %bool 3
+      %false = OpConstantFalse %bool
+       %true = OpConstantTrue %bool
+          %v = OpConstantComposite %v3bool %false %true %false
+       %void = OpTypeVoid
+          %6 = OpTypeFunction %void
+%unused_entry_point = OpFunction %void None %6
+          %9 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/test/expressions/type_ctor/vec3/explicit/bool.wgsl.expected.wgsl b/test/expressions/type_ctor/vec3/explicit/bool.wgsl.expected.wgsl
new file mode 100644
index 0000000..0acf3bf
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/bool.wgsl.expected.wgsl
@@ -0,0 +1 @@
+let v = vec3<bool>(false, true, false);
diff --git a/test/expressions/type_ctor/vec3/explicit/f32.wgsl b/test/expressions/type_ctor/vec3/explicit/f32.wgsl
new file mode 100644
index 0000000..2164502
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/f32.wgsl
@@ -0,0 +1 @@
+let v = vec3<f32>(0.0, 1.0, 2.0);
diff --git a/test/expressions/type_ctor/vec3/explicit/f32.wgsl.expected.hlsl b/test/expressions/type_ctor/vec3/explicit/f32.wgsl.expected.hlsl
new file mode 100644
index 0000000..daa5a1c
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/f32.wgsl.expected.hlsl
@@ -0,0 +1,6 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+  return;
+}
+
+static const float3 v = float3(0.0f, 1.0f, 2.0f);
diff --git a/test/expressions/type_ctor/vec3/explicit/f32.wgsl.expected.msl b/test/expressions/type_ctor/vec3/explicit/f32.wgsl.expected.msl
new file mode 100644
index 0000000..6b8d4ff
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/f32.wgsl.expected.msl
@@ -0,0 +1,4 @@
+#include <metal_stdlib>
+
+using namespace metal;
+constant float3 v = float3(0.0f, 1.0f, 2.0f);
diff --git a/test/expressions/type_ctor/vec3/explicit/f32.wgsl.expected.spvasm b/test/expressions/type_ctor/vec3/explicit/f32.wgsl.expected.spvasm
new file mode 100644
index 0000000..62e8bc3
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/f32.wgsl.expected.spvasm
@@ -0,0 +1,23 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 11
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+               OpExecutionMode %unused_entry_point LocalSize 1 1 1
+               OpName %v "v"
+               OpName %unused_entry_point "unused_entry_point"
+      %float = OpTypeFloat 32
+    %v3float = OpTypeVector %float 3
+    %float_0 = OpConstant %float 0
+    %float_1 = OpConstant %float 1
+    %float_2 = OpConstant %float 2
+          %v = OpConstantComposite %v3float %float_0 %float_1 %float_2
+       %void = OpTypeVoid
+          %7 = OpTypeFunction %void
+%unused_entry_point = OpFunction %void None %7
+         %10 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/test/expressions/type_ctor/vec3/explicit/f32.wgsl.expected.wgsl b/test/expressions/type_ctor/vec3/explicit/f32.wgsl.expected.wgsl
new file mode 100644
index 0000000..2164502
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/f32.wgsl.expected.wgsl
@@ -0,0 +1 @@
+let v = vec3<f32>(0.0, 1.0, 2.0);
diff --git a/test/expressions/type_ctor/vec3/explicit/i32.wgsl b/test/expressions/type_ctor/vec3/explicit/i32.wgsl
new file mode 100644
index 0000000..7d28b9e
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/i32.wgsl
@@ -0,0 +1 @@
+let v = vec3<i32>(0, 1, 2);
diff --git a/test/expressions/type_ctor/vec3/explicit/i32.wgsl.expected.hlsl b/test/expressions/type_ctor/vec3/explicit/i32.wgsl.expected.hlsl
new file mode 100644
index 0000000..9bc1dc4
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/i32.wgsl.expected.hlsl
@@ -0,0 +1,6 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+  return;
+}
+
+static const int3 v = int3(0, 1, 2);
diff --git a/test/expressions/type_ctor/vec3/explicit/i32.wgsl.expected.msl b/test/expressions/type_ctor/vec3/explicit/i32.wgsl.expected.msl
new file mode 100644
index 0000000..941501e
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/i32.wgsl.expected.msl
@@ -0,0 +1,4 @@
+#include <metal_stdlib>
+
+using namespace metal;
+constant int3 v = int3(0, 1, 2);
diff --git a/test/expressions/type_ctor/vec3/explicit/i32.wgsl.expected.spvasm b/test/expressions/type_ctor/vec3/explicit/i32.wgsl.expected.spvasm
new file mode 100644
index 0000000..fe0276e
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/i32.wgsl.expected.spvasm
@@ -0,0 +1,23 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 11
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+               OpExecutionMode %unused_entry_point LocalSize 1 1 1
+               OpName %v "v"
+               OpName %unused_entry_point "unused_entry_point"
+        %int = OpTypeInt 32 1
+      %v3int = OpTypeVector %int 3
+      %int_0 = OpConstant %int 0
+      %int_1 = OpConstant %int 1
+      %int_2 = OpConstant %int 2
+          %v = OpConstantComposite %v3int %int_0 %int_1 %int_2
+       %void = OpTypeVoid
+          %7 = OpTypeFunction %void
+%unused_entry_point = OpFunction %void None %7
+         %10 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/test/expressions/type_ctor/vec3/explicit/i32.wgsl.expected.wgsl b/test/expressions/type_ctor/vec3/explicit/i32.wgsl.expected.wgsl
new file mode 100644
index 0000000..7d28b9e
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/i32.wgsl.expected.wgsl
@@ -0,0 +1 @@
+let v = vec3<i32>(0, 1, 2);
diff --git a/test/expressions/type_ctor/vec3/explicit/u32.wgsl b/test/expressions/type_ctor/vec3/explicit/u32.wgsl
new file mode 100644
index 0000000..111a1d3
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/u32.wgsl
@@ -0,0 +1 @@
+let v = vec3<u32>(0u, 1u, 2u);
diff --git a/test/expressions/type_ctor/vec3/explicit/u32.wgsl.expected.hlsl b/test/expressions/type_ctor/vec3/explicit/u32.wgsl.expected.hlsl
new file mode 100644
index 0000000..18899ea
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/u32.wgsl.expected.hlsl
@@ -0,0 +1,6 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+  return;
+}
+
+static const uint3 v = uint3(0u, 1u, 2u);
diff --git a/test/expressions/type_ctor/vec3/explicit/u32.wgsl.expected.msl b/test/expressions/type_ctor/vec3/explicit/u32.wgsl.expected.msl
new file mode 100644
index 0000000..d2a07cf
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/u32.wgsl.expected.msl
@@ -0,0 +1,4 @@
+#include <metal_stdlib>
+
+using namespace metal;
+constant uint3 v = uint3(0u, 1u, 2u);
diff --git a/test/expressions/type_ctor/vec3/explicit/u32.wgsl.expected.spvasm b/test/expressions/type_ctor/vec3/explicit/u32.wgsl.expected.spvasm
new file mode 100644
index 0000000..e4b4797
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/u32.wgsl.expected.spvasm
@@ -0,0 +1,23 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 11
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+               OpExecutionMode %unused_entry_point LocalSize 1 1 1
+               OpName %v "v"
+               OpName %unused_entry_point "unused_entry_point"
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
+     %uint_2 = OpConstant %uint 2
+          %v = OpConstantComposite %v3uint %uint_0 %uint_1 %uint_2
+       %void = OpTypeVoid
+          %7 = OpTypeFunction %void
+%unused_entry_point = OpFunction %void None %7
+         %10 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/test/expressions/type_ctor/vec3/explicit/u32.wgsl.expected.wgsl b/test/expressions/type_ctor/vec3/explicit/u32.wgsl.expected.wgsl
new file mode 100644
index 0000000..111a1d3
--- /dev/null
+++ b/test/expressions/type_ctor/vec3/explicit/u32.wgsl.expected.wgsl
@@ -0,0 +1 @@
+let v = vec3<u32>(0u, 1u, 2u);
diff --git a/test/expressions/type_ctor/vec4/explicit/bool.wgsl b/test/expressions/type_ctor/vec4/explicit/bool.wgsl
new file mode 100644
index 0000000..70cb499
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/bool.wgsl
@@ -0,0 +1 @@
+let v = vec4<bool>(false, true, false, true);
diff --git a/test/expressions/type_ctor/vec4/explicit/bool.wgsl.expected.hlsl b/test/expressions/type_ctor/vec4/explicit/bool.wgsl.expected.hlsl
new file mode 100644
index 0000000..af7e30f
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/bool.wgsl.expected.hlsl
@@ -0,0 +1,6 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+  return;
+}
+
+static const bool4 v = bool4(false, true, false, true);
diff --git a/test/expressions/type_ctor/vec4/explicit/bool.wgsl.expected.msl b/test/expressions/type_ctor/vec4/explicit/bool.wgsl.expected.msl
new file mode 100644
index 0000000..2d872de
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/bool.wgsl.expected.msl
@@ -0,0 +1,4 @@
+#include <metal_stdlib>
+
+using namespace metal;
+constant bool4 v = bool4(false, true, false, true);
diff --git a/test/expressions/type_ctor/vec4/explicit/bool.wgsl.expected.spvasm b/test/expressions/type_ctor/vec4/explicit/bool.wgsl.expected.spvasm
new file mode 100644
index 0000000..1ecbff1
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/bool.wgsl.expected.spvasm
@@ -0,0 +1,22 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 10
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+               OpExecutionMode %unused_entry_point LocalSize 1 1 1
+               OpName %v "v"
+               OpName %unused_entry_point "unused_entry_point"
+       %bool = OpTypeBool
+     %v4bool = OpTypeVector %bool 4
+      %false = OpConstantFalse %bool
+       %true = OpConstantTrue %bool
+          %v = OpConstantComposite %v4bool %false %true %false %true
+       %void = OpTypeVoid
+          %6 = OpTypeFunction %void
+%unused_entry_point = OpFunction %void None %6
+          %9 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/test/expressions/type_ctor/vec4/explicit/bool.wgsl.expected.wgsl b/test/expressions/type_ctor/vec4/explicit/bool.wgsl.expected.wgsl
new file mode 100644
index 0000000..70cb499
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/bool.wgsl.expected.wgsl
@@ -0,0 +1 @@
+let v = vec4<bool>(false, true, false, true);
diff --git a/test/expressions/type_ctor/vec4/explicit/f32.wgsl b/test/expressions/type_ctor/vec4/explicit/f32.wgsl
new file mode 100644
index 0000000..3e7b8b6
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/f32.wgsl
@@ -0,0 +1 @@
+let v = vec4<f32>(0.0, 1.0, 2.0, 3.0);
diff --git a/test/expressions/type_ctor/vec4/explicit/f32.wgsl.expected.hlsl b/test/expressions/type_ctor/vec4/explicit/f32.wgsl.expected.hlsl
new file mode 100644
index 0000000..bd679f3
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/f32.wgsl.expected.hlsl
@@ -0,0 +1,6 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+  return;
+}
+
+static const float4 v = float4(0.0f, 1.0f, 2.0f, 3.0f);
diff --git a/test/expressions/type_ctor/vec4/explicit/f32.wgsl.expected.msl b/test/expressions/type_ctor/vec4/explicit/f32.wgsl.expected.msl
new file mode 100644
index 0000000..08af725
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/f32.wgsl.expected.msl
@@ -0,0 +1,4 @@
+#include <metal_stdlib>
+
+using namespace metal;
+constant float4 v = float4(0.0f, 1.0f, 2.0f, 3.0f);
diff --git a/test/expressions/type_ctor/vec4/explicit/f32.wgsl.expected.spvasm b/test/expressions/type_ctor/vec4/explicit/f32.wgsl.expected.spvasm
new file mode 100644
index 0000000..783aa84
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/f32.wgsl.expected.spvasm
@@ -0,0 +1,24 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 12
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+               OpExecutionMode %unused_entry_point LocalSize 1 1 1
+               OpName %v "v"
+               OpName %unused_entry_point "unused_entry_point"
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+    %float_0 = OpConstant %float 0
+    %float_1 = OpConstant %float 1
+    %float_2 = OpConstant %float 2
+    %float_3 = OpConstant %float 3
+          %v = OpConstantComposite %v4float %float_0 %float_1 %float_2 %float_3
+       %void = OpTypeVoid
+          %8 = OpTypeFunction %void
+%unused_entry_point = OpFunction %void None %8
+         %11 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/test/expressions/type_ctor/vec4/explicit/f32.wgsl.expected.wgsl b/test/expressions/type_ctor/vec4/explicit/f32.wgsl.expected.wgsl
new file mode 100644
index 0000000..3e7b8b6
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/f32.wgsl.expected.wgsl
@@ -0,0 +1 @@
+let v = vec4<f32>(0.0, 1.0, 2.0, 3.0);
diff --git a/test/expressions/type_ctor/vec4/explicit/i32.wgsl b/test/expressions/type_ctor/vec4/explicit/i32.wgsl
new file mode 100644
index 0000000..9c86a2e
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/i32.wgsl
@@ -0,0 +1 @@
+let v = vec4<i32>(0, 1, 2, 3);
diff --git a/test/expressions/type_ctor/vec4/explicit/i32.wgsl.expected.hlsl b/test/expressions/type_ctor/vec4/explicit/i32.wgsl.expected.hlsl
new file mode 100644
index 0000000..58b86ce
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/i32.wgsl.expected.hlsl
@@ -0,0 +1,6 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+  return;
+}
+
+static const int4 v = int4(0, 1, 2, 3);
diff --git a/test/expressions/type_ctor/vec4/explicit/i32.wgsl.expected.msl b/test/expressions/type_ctor/vec4/explicit/i32.wgsl.expected.msl
new file mode 100644
index 0000000..b4294a3
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/i32.wgsl.expected.msl
@@ -0,0 +1,4 @@
+#include <metal_stdlib>
+
+using namespace metal;
+constant int4 v = int4(0, 1, 2, 3);
diff --git a/test/expressions/type_ctor/vec4/explicit/i32.wgsl.expected.spvasm b/test/expressions/type_ctor/vec4/explicit/i32.wgsl.expected.spvasm
new file mode 100644
index 0000000..88201cc
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/i32.wgsl.expected.spvasm
@@ -0,0 +1,24 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 12
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+               OpExecutionMode %unused_entry_point LocalSize 1 1 1
+               OpName %v "v"
+               OpName %unused_entry_point "unused_entry_point"
+        %int = OpTypeInt 32 1
+      %v4int = OpTypeVector %int 4
+      %int_0 = OpConstant %int 0
+      %int_1 = OpConstant %int 1
+      %int_2 = OpConstant %int 2
+      %int_3 = OpConstant %int 3
+          %v = OpConstantComposite %v4int %int_0 %int_1 %int_2 %int_3
+       %void = OpTypeVoid
+          %8 = OpTypeFunction %void
+%unused_entry_point = OpFunction %void None %8
+         %11 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/test/expressions/type_ctor/vec4/explicit/i32.wgsl.expected.wgsl b/test/expressions/type_ctor/vec4/explicit/i32.wgsl.expected.wgsl
new file mode 100644
index 0000000..9c86a2e
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/i32.wgsl.expected.wgsl
@@ -0,0 +1 @@
+let v = vec4<i32>(0, 1, 2, 3);
diff --git a/test/expressions/type_ctor/vec4/explicit/u32.wgsl b/test/expressions/type_ctor/vec4/explicit/u32.wgsl
new file mode 100644
index 0000000..feaa000
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/u32.wgsl
@@ -0,0 +1 @@
+let v = vec4<u32>(0u, 1u, 2u, 3u);
diff --git a/test/expressions/type_ctor/vec4/explicit/u32.wgsl.expected.hlsl b/test/expressions/type_ctor/vec4/explicit/u32.wgsl.expected.hlsl
new file mode 100644
index 0000000..014390a
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/u32.wgsl.expected.hlsl
@@ -0,0 +1,6 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+  return;
+}
+
+static const uint4 v = uint4(0u, 1u, 2u, 3u);
diff --git a/test/expressions/type_ctor/vec4/explicit/u32.wgsl.expected.msl b/test/expressions/type_ctor/vec4/explicit/u32.wgsl.expected.msl
new file mode 100644
index 0000000..c51f246
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/u32.wgsl.expected.msl
@@ -0,0 +1,4 @@
+#include <metal_stdlib>
+
+using namespace metal;
+constant uint4 v = uint4(0u, 1u, 2u, 3u);
diff --git a/test/expressions/type_ctor/vec4/explicit/u32.wgsl.expected.spvasm b/test/expressions/type_ctor/vec4/explicit/u32.wgsl.expected.spvasm
new file mode 100644
index 0000000..23b7d44
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/u32.wgsl.expected.spvasm
@@ -0,0 +1,24 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 12
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+               OpExecutionMode %unused_entry_point LocalSize 1 1 1
+               OpName %v "v"
+               OpName %unused_entry_point "unused_entry_point"
+       %uint = OpTypeInt 32 0
+     %v4uint = OpTypeVector %uint 4
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
+     %uint_2 = OpConstant %uint 2
+     %uint_3 = OpConstant %uint 3
+          %v = OpConstantComposite %v4uint %uint_0 %uint_1 %uint_2 %uint_3
+       %void = OpTypeVoid
+          %8 = OpTypeFunction %void
+%unused_entry_point = OpFunction %void None %8
+         %11 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/test/expressions/type_ctor/vec4/explicit/u32.wgsl.expected.wgsl b/test/expressions/type_ctor/vec4/explicit/u32.wgsl.expected.wgsl
new file mode 100644
index 0000000..feaa000
--- /dev/null
+++ b/test/expressions/type_ctor/vec4/explicit/u32.wgsl.expected.wgsl
@@ -0,0 +1 @@
+let v = vec4<u32>(0u, 1u, 2u, 3u);