Import Tint changes from Dawn
Changes:
- 1a2543e754a31ed889566b9bb93d6bce83ea9eb7 [tint][cmd] Don't vary HLSL output based on validation mode by Ben Clayton <bclayton@google.com>
- 0e15f4ab994611a50eb63ff35c8d2a430f5f358a [spirv-reader] Handle OpCompositeExtract by James Price <jrprice@google.com>
- 383c99157767e8a9de5cef59fc783a20b6235302 [spirv-reader] Handle OpCompositeConstruct by James Price <jrprice@google.com>
- a158d5164ebc9406e3e331052f6ddf1dfad6c76c spirv-reader: Fix invalid memory semantics in test by James Price <jrprice@google.com>
GitOrigin-RevId: 1a2543e754a31ed889566b9bb93d6bce83ea9eb7
Change-Id: Ie963cf5d8dc9f396dbd503317082f14f330e59a5
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/170520
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/cmd/tint/main.cc b/src/tint/cmd/tint/main.cc
index ff85ff7..474088e 100644
--- a/src/tint/cmd/tint/main.cc
+++ b/src/tint/cmd/tint/main.cc
@@ -145,6 +145,8 @@
#if TINT_BUILD_HLSL_WRITER
constexpr uint32_t kMinShaderModelForDXC = 60u;
constexpr uint32_t kMaxSupportedShaderModelForDXC = 66u;
+constexpr uint32_t kMinShaderModelForDP4aInHLSL = 64u;
+constexpr uint32_t kMinShaderModelForPackUnpack4x8InHLSL = 66u;
#endif // TINT_BUILD_HLSL_WRITER
struct Options {
@@ -917,17 +919,9 @@
tint::cmd::GenerateExternalTextureBindings(program);
gen_options.root_constant_binding_point = options.hlsl_root_constant_binding_point;
gen_options.pixel_local_options = options.pixel_local_options;
- if (must_validate_dxc) {
- constexpr uint32_t kMinShaderModelForDP4aInHLSL = 64u;
- constexpr uint32_t kMinShaderModelForPackUnPack4x8InHLSL = 66u;
- gen_options.polyfill_dot_4x8_packed =
- options.hlsl_shader_model < kMinShaderModelForDP4aInHLSL;
- gen_options.polyfill_pack_unpack_4x8 =
- options.hlsl_shader_model < kMinShaderModelForPackUnPack4x8InHLSL;
- } else {
- gen_options.polyfill_dot_4x8_packed = true;
- gen_options.polyfill_pack_unpack_4x8 = true;
- }
+ gen_options.polyfill_dot_4x8_packed = options.hlsl_shader_model < kMinShaderModelForDP4aInHLSL;
+ gen_options.polyfill_pack_unpack_4x8 =
+ options.hlsl_shader_model < kMinShaderModelForPackUnpack4x8InHLSL;
auto result = tint::hlsl::writer::Generate(program, gen_options);
if (result != tint::Success) {
tint::cmd::PrintWGSL(std::cerr, program);
diff --git a/src/tint/lang/spirv/reader/ast_parser/parser_test.cc b/src/tint/lang/spirv/reader/ast_parser/parser_test.cc
index 404e925..5805440 100644
--- a/src/tint/lang/spirv/reader/ast_parser/parser_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/parser_test.cc
@@ -103,7 +103,7 @@
%_ptr_Input_vec3u = OpTypePointer Input %vec3u
%uint_0 = OpConstant %uint 0
%uint_2 = OpConstant %uint 2
- %uint_8 = OpConstant %uint 8
+ %uint_264 = OpConstant %uint 264
%wgid = OpVariable %_ptr_Input_vec3u Input
%void = OpTypeVoid
%bool = OpTypeBool
@@ -116,7 +116,7 @@
OpSelectionMerge %merge None
OpBranchConditional %condition %true_branch %merge
%true_branch = OpLabel
- OpControlBarrier %uint_2 %uint_2 %uint_8
+ OpControlBarrier %uint_2 %uint_2 %uint_264
OpBranch %merge
%merge = OpLabel
OpReturn
diff --git a/src/tint/lang/spirv/reader/parser/BUILD.bazel b/src/tint/lang/spirv/reader/parser/BUILD.bazel
index 2bfaad6..22ae352 100644
--- a/src/tint/lang/spirv/reader/parser/BUILD.bazel
+++ b/src/tint/lang/spirv/reader/parser/BUILD.bazel
@@ -79,6 +79,7 @@
name = "test",
alwayslink = True,
srcs = [
+ "composite_test.cc",
"constant_test.cc",
"function_test.cc",
"helper_test.h",
diff --git a/src/tint/lang/spirv/reader/parser/BUILD.cmake b/src/tint/lang/spirv/reader/parser/BUILD.cmake
index c8abe87..52c7c0c 100644
--- a/src/tint/lang/spirv/reader/parser/BUILD.cmake
+++ b/src/tint/lang/spirv/reader/parser/BUILD.cmake
@@ -85,6 +85,7 @@
# Condition: TINT_BUILD_SPV_READER
################################################################################
tint_add_target(tint_lang_spirv_reader_parser_test test
+ lang/spirv/reader/parser/composite_test.cc
lang/spirv/reader/parser/constant_test.cc
lang/spirv/reader/parser/function_test.cc
lang/spirv/reader/parser/helper_test.h
diff --git a/src/tint/lang/spirv/reader/parser/BUILD.gn b/src/tint/lang/spirv/reader/parser/BUILD.gn
index 26c2954..f6c3fba 100644
--- a/src/tint/lang/spirv/reader/parser/BUILD.gn
+++ b/src/tint/lang/spirv/reader/parser/BUILD.gn
@@ -86,6 +86,7 @@
if (tint_build_spv_reader) {
tint_unittests_source_set("unittests") {
sources = [
+ "composite_test.cc",
"constant_test.cc",
"function_test.cc",
"helper_test.h",
diff --git a/src/tint/lang/spirv/reader/parser/composite_test.cc b/src/tint/lang/spirv/reader/parser/composite_test.cc
new file mode 100644
index 0000000..6a0ce9f
--- /dev/null
+++ b/src/tint/lang/spirv/reader/parser/composite_test.cc
@@ -0,0 +1,459 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/spirv/reader/parser/helper_test.h"
+
+namespace tint::spirv::reader {
+namespace {
+
+TEST_F(SpirvParserTest, CompositeConstruct_Vector) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %vec4u = OpTypeVector %u32 4
+ %ep_type = OpTypeFunction %void
+ %fn_type = OpTypeFunction %vec4u
+ %u32_1 = OpConstant %u32 1
+ %u32_2 = OpConstant %u32 2
+ %u32_3 = OpConstant %u32 3
+ %u32_4 = OpConstant %u32 4
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ %foo = OpFunction %vec4u None %fn_type
+ %foo_start = OpLabel
+ %vec = OpCompositeConstruct %vec4u %u32_1 %u32_2 %u32_3 %u32_4
+ OpReturnValue %vec
+ OpFunctionEnd
+)",
+ R"(
+ %b2 = block {
+ %3:vec4<u32> = construct 1u, 2u, 3u, 4u
+ ret %3
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, CompositeConstruct_Matrix) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %f32 = OpTypeFloat 32
+ %vec3f = OpTypeVector %f32 3
+ %mat4x3 = OpTypeMatrix %vec3f 4
+ %ep_type = OpTypeFunction %void
+ %fn_type = OpTypeFunction %mat4x3
+ %f32_1 = OpConstant %f32 1.0
+ %f32_2 = OpConstant %f32 2.0
+ %f32_3 = OpConstant %f32 3.0
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ %foo = OpFunction %mat4x3 None %fn_type
+ %foo_start = OpLabel
+ %col_0 = OpCompositeConstruct %vec3f %f32_1 %f32_2 %f32_3
+ %col_1 = OpCompositeConstruct %vec3f %f32_2 %f32_3 %f32_1
+ %col_2 = OpCompositeConstruct %vec3f %f32_3 %f32_2 %f32_1
+ %col_3 = OpCompositeConstruct %vec3f %f32_3 %f32_3 %f32_3
+ %mat = OpCompositeConstruct %mat4x3 %col_0 %col_1 %col_2 %col_3
+ OpReturnValue %mat
+ OpFunctionEnd
+)",
+ R"(
+ %b2 = block {
+ %3:vec3<f32> = construct 1.0f, 2.0f, 3.0f
+ %4:vec3<f32> = construct 2.0f, 3.0f, 1.0f
+ %5:vec3<f32> = construct 3.0f, 2.0f, 1.0f
+ %6:vec3<f32> = construct 3.0f, 3.0f, 3.0f
+ %7:mat4x3<f32> = construct %3, %4, %5, %6
+ ret %7
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, CompositeConstruct_Array) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %ep_type = OpTypeFunction %void
+ %u32_1 = OpConstant %u32 1
+ %u32_2 = OpConstant %u32 2
+ %u32_3 = OpConstant %u32 3
+ %u32_4 = OpConstant %u32 4
+ %arr_ty = OpTypeArray %u32 %u32_4
+ %fn_type = OpTypeFunction %arr_ty
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ %foo = OpFunction %arr_ty None %fn_type
+ %foo_start = OpLabel
+ %arr = OpCompositeConstruct %arr_ty %u32_1 %u32_2 %u32_3 %u32_4
+ OpReturnValue %arr
+ OpFunctionEnd
+)",
+ R"(
+ %b2 = block {
+ %3:array<u32, 4> = construct 1u, 2u, 3u, 4u
+ ret %3
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, CompositeConstruct_ArrayOfVec) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %vec4u = OpTypeVector %u32 4
+ %ep_type = OpTypeFunction %void
+ %u32_1 = OpConstant %u32 1
+ %u32_2 = OpConstant %u32 2
+ %u32_3 = OpConstant %u32 3
+ %u32_4 = OpConstant %u32 4
+ %arr_ty = OpTypeArray %vec4u %u32_4
+ %fn_type = OpTypeFunction %arr_ty
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ %foo = OpFunction %arr_ty None %fn_type
+ %foo_start = OpLabel
+ %el_0 = OpCompositeConstruct %vec4u %u32_1 %u32_2 %u32_3 %u32_4
+ %el_1 = OpCompositeConstruct %vec4u %u32_2 %u32_3 %u32_4 %u32_1
+ %el_2 = OpCompositeConstruct %vec4u %u32_3 %u32_4 %u32_1 %u32_2
+ %el_3 = OpCompositeConstruct %vec4u %u32_4 %u32_1 %u32_2 %u32_3
+ %arr = OpCompositeConstruct %arr_ty %el_0 %el_1 %el_2 %el_3
+ OpReturnValue %arr
+ OpFunctionEnd
+)",
+ R"(
+ %b2 = block {
+ %3:vec4<u32> = construct 1u, 2u, 3u, 4u
+ %4:vec4<u32> = construct 2u, 3u, 4u, 1u
+ %5:vec4<u32> = construct 3u, 4u, 1u, 2u
+ %6:vec4<u32> = construct 4u, 1u, 2u, 3u
+ %7:array<vec4<u32>, 4> = construct %3, %4, %5, %6
+ ret %7
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, CompositeConstruct_Struct) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %vec4u = OpTypeVector %u32 4
+ %ep_type = OpTypeFunction %void
+ %u32_1 = OpConstant %u32 1
+ %u32_2 = OpConstant %u32 2
+ %u32_3 = OpConstant %u32 3
+ %u32_4 = OpConstant %u32 4
+ %arr_ty = OpTypeArray %vec4u %u32_2
+ %str_ty = OpTypeStruct %u32 %vec4u %arr_ty
+ %fn_type = OpTypeFunction %str_ty
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ %foo = OpFunction %str_ty None %fn_type
+ %foo_start = OpLabel
+ %el_0 = OpCompositeConstruct %vec4u %u32_1 %u32_2 %u32_3 %u32_4
+ %el_1 = OpCompositeConstruct %vec4u %u32_2 %u32_3 %u32_4 %u32_1
+ %el_2 = OpCompositeConstruct %vec4u %u32_3 %u32_4 %u32_1 %u32_2
+ %arr = OpCompositeConstruct %arr_ty %el_1 %el_2
+ %str = OpCompositeConstruct %str_ty %u32_4 %el_0 %arr
+ OpReturnValue %str
+ OpFunctionEnd
+)",
+ R"(
+tint_symbol_3 = struct @align(16) {
+ tint_symbol:u32 @offset(0)
+ tint_symbol_1:vec4<u32> @offset(16)
+ tint_symbol_2:array<vec4<u32>, 2> @offset(32)
+}
+
+%main = @compute @workgroup_size(1, 1, 1) func():void -> %b1 {
+ %b1 = block {
+ ret
+ }
+}
+%2 = func():tint_symbol_3 -> %b2 {
+ %b2 = block {
+ %3:vec4<u32> = construct 1u, 2u, 3u, 4u
+ %4:vec4<u32> = construct 2u, 3u, 4u, 1u
+ %5:vec4<u32> = construct 3u, 4u, 1u, 2u
+ %6:array<vec4<u32>, 2> = construct %4, %5
+ %7:tint_symbol_3 = construct 4u, %3, %6
+ ret %7
+ }
+}
+)");
+}
+
+TEST_F(SpirvParserTest, CompositeExtract_Vector) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %vec4u = OpTypeVector %u32 4
+ %ep_type = OpTypeFunction %void
+ %fn_type = OpTypeFunction %u32 %vec4u
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ %foo = OpFunction %u32 None %fn_type
+ %vec = OpFunctionParameter %vec4u
+ %foo_start = OpLabel
+ %extract = OpCompositeExtract %u32 %vec 2
+ OpReturnValue %extract
+ OpFunctionEnd
+)",
+ R"(
+%2 = func(%3:vec4<u32>):u32 -> %b2 {
+ %b2 = block {
+ %4:u32 = access %3, 2u
+ ret %4
+ }
+}
+)");
+}
+
+TEST_F(SpirvParserTest, CompositeExtract_MatrixColumn) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %f32 = OpTypeFloat 32
+ %vec3f = OpTypeVector %f32 3
+ %mat4x3 = OpTypeMatrix %vec3f 4
+ %ep_type = OpTypeFunction %void
+ %fn_type = OpTypeFunction %vec3f %mat4x3
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ %foo = OpFunction %vec3f None %fn_type
+ %mat = OpFunctionParameter %mat4x3
+ %foo_start = OpLabel
+ %extract = OpCompositeExtract %vec3f %mat 2
+ OpReturnValue %extract
+ OpFunctionEnd
+)",
+ R"(
+%2 = func(%3:mat4x3<f32>):vec3<f32> -> %b2 {
+ %b2 = block {
+ %4:vec3<f32> = access %3, 2u
+ ret %4
+ }
+}
+)");
+}
+
+TEST_F(SpirvParserTest, CompositeExtract_MatrixElement) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %f32 = OpTypeFloat 32
+ %vec3f = OpTypeVector %f32 3
+ %mat4x3 = OpTypeMatrix %vec3f 4
+ %ep_type = OpTypeFunction %void
+ %fn_type = OpTypeFunction %f32 %mat4x3
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ %foo = OpFunction %f32 None %fn_type
+ %mat = OpFunctionParameter %mat4x3
+ %foo_start = OpLabel
+ %extract = OpCompositeExtract %f32 %mat 2 1
+ OpReturnValue %extract
+ OpFunctionEnd
+)",
+ R"(
+%2 = func(%3:mat4x3<f32>):f32 -> %b2 {
+ %b2 = block {
+ %4:f32 = access %3, 2u, 1u
+ ret %4
+ }
+}
+)");
+}
+
+TEST_F(SpirvParserTest, CompositeExtract_Array) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %u32_4 = OpConstant %u32 4
+ %arr_ty = OpTypeArray %u32 %u32_4
+ %ep_type = OpTypeFunction %void
+ %fn_type = OpTypeFunction %u32 %arr_ty
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ %foo = OpFunction %u32 None %fn_type
+ %arr = OpFunctionParameter %arr_ty
+ %foo_start = OpLabel
+ %extract = OpCompositeExtract %u32 %arr 2
+ OpReturnValue %extract
+ OpFunctionEnd
+)",
+ R"(
+%2 = func(%3:array<u32, 4>):u32 -> %b2 {
+ %b2 = block {
+ %4:u32 = access %3, 2u
+ ret %4
+ }
+}
+)");
+}
+
+TEST_F(SpirvParserTest, CompositeExtract_ArrayOfVec) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %vec3u = OpTypeVector %u32 3
+ %u32_4 = OpConstant %u32 4
+ %arr_ty = OpTypeArray %vec3u %u32_4
+ %ep_type = OpTypeFunction %void
+ %fn_type = OpTypeFunction %u32 %arr_ty
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ %foo = OpFunction %u32 None %fn_type
+ %arr = OpFunctionParameter %arr_ty
+ %foo_start = OpLabel
+ %extract = OpCompositeExtract %u32 %arr 1 2
+ OpReturnValue %extract
+ OpFunctionEnd
+)",
+ R"(
+%2 = func(%3:array<vec3<u32>, 4>):u32 -> %b2 {
+ %b2 = block {
+ %4:u32 = access %3, 1u, 2u
+ ret %4
+ }
+}
+)");
+}
+
+TEST_F(SpirvParserTest, CompositeExtract_Struct) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %str_ty = OpTypeStruct %u32 %u32
+ %ep_type = OpTypeFunction %void
+ %fn_type = OpTypeFunction %u32 %str_ty
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ %foo = OpFunction %u32 None %fn_type
+ %str = OpFunctionParameter %str_ty
+ %foo_start = OpLabel
+ %extract = OpCompositeExtract %u32 %str 1
+ OpReturnValue %extract
+ OpFunctionEnd
+)",
+ R"(
+tint_symbol_2 = struct @align(4) {
+ tint_symbol:u32 @offset(0)
+ tint_symbol_1:u32 @offset(4)
+}
+
+%main = @compute @workgroup_size(1, 1, 1) func():void -> %b1 {
+ %b1 = block {
+ ret
+ }
+}
+%2 = func(%3:tint_symbol_2):u32 -> %b2 {
+ %b2 = block {
+ %4:u32 = access %3, 1u
+ ret %4
+ }
+}
+)");
+}
+
+} // namespace
+} // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/parser/parser.cc b/src/tint/lang/spirv/reader/parser/parser.cc
index 56a3d47..6fe4eb9 100644
--- a/src/tint/lang/spirv/reader/parser/parser.cc
+++ b/src/tint/lang/spirv/reader/parser/parser.cc
@@ -420,6 +420,12 @@
case spv::Op::OpInBoundsAccessChain:
EmitAccess(inst);
break;
+ case spv::Op::OpCompositeConstruct:
+ EmitConstruct(inst);
+ break;
+ case spv::Op::OpCompositeExtract:
+ EmitCompositeExtract(inst);
+ break;
case spv::Op::OpFunctionCall:
EmitFunctionCall(inst);
break;
@@ -457,6 +463,27 @@
Emit(access, inst.result_id());
}
+ /// @param inst the SPIR-V instruction for OpCompositeExtract
+ void EmitCompositeExtract(const spvtools::opt::Instruction& inst) {
+ Vector<core::ir::Value*, 4> indices;
+ for (uint32_t i = 3; i < inst.NumOperandWords(); i++) {
+ indices.Push(b_.Constant(u32(inst.GetSingleWordOperand(i))));
+ }
+ auto* object = Value(inst.GetSingleWordOperand(2));
+ auto* access = b_.Access(Type(inst.type_id()), object, std::move(indices));
+ Emit(access, inst.result_id());
+ }
+
+ /// @param inst the SPIR-V instruction for OpCompositeConstruct
+ void EmitConstruct(const spvtools::opt::Instruction& inst) {
+ Vector<core::ir::Value*, 4> values;
+ for (uint32_t i = 2; i < inst.NumOperandWords(); i++) {
+ values.Push(Value(inst.GetSingleWordOperand(i)));
+ }
+ auto* construct = b_.Construct(Type(inst.type_id()), std::move(values));
+ Emit(construct, inst.result_id());
+ }
+
/// @param inst the SPIR-V instruction for OpFunctionCall
void EmitFunctionCall(const spvtools::opt::Instruction& inst) {
// TODO(crbug.com/tint/1907): Capture result.