tint/test: Regenerate expectations
Fix collision of two CLs landing with different expectations.
Change-Id: I44eb904b552f635e37dd51dcc94329fbc34af031
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/94685
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.msl b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.msl
index 896696e..943a64c 100644
--- a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.msl
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.msl
@@ -1,31 +1,20 @@
#include <metal_stdlib>
using namespace metal;
-struct tint_array_wrapper {
- uint arr[1];
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
};
-struct tint_array_wrapper_1 {
- tint_array_wrapper arr[2];
-};
-
-struct tint_array_wrapper_2 {
- tint_array_wrapper_1 arr[3];
-};
-
-struct tint_array_wrapper_5 {
- atomic_uint arr[1];
-};
-
-struct tint_array_wrapper_4 {
- tint_array_wrapper_5 arr[2];
-};
-
-struct tint_array_wrapper_3 {
- tint_array_wrapper_4 arr[3];
-};
-
-void compute_main_inner(uint local_invocation_index, threadgroup tint_array_wrapper_3* const tint_symbol) {
+void compute_main_inner(uint local_invocation_index, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol) {
uint idx = 0u;
idx = local_invocation_index;
while (true) {
@@ -36,29 +25,29 @@
uint const x_31 = idx;
uint const x_33 = idx;
uint const x_35 = idx;
- atomic_store_explicit(&((*(tint_symbol)).arr[(x_31 / 2u)].arr[(x_33 % 2u)].arr[(x_35 % 1u)]), 0u, memory_order_relaxed);
+ atomic_store_explicit(&((*(tint_symbol))[(x_31 / 2u)][(x_33 % 2u)][(x_35 % 1u)]), 0u, memory_order_relaxed);
{
uint const x_42 = idx;
idx = (x_42 + 1u);
}
}
threadgroup_barrier(mem_flags::mem_threadgroup);
- atomic_store_explicit(&((*(tint_symbol)).arr[2].arr[1].arr[0]), 1u, memory_order_relaxed);
+ atomic_store_explicit(&((*(tint_symbol))[2][1][0]), 1u, memory_order_relaxed);
return;
}
-void compute_main_1(thread uint* const tint_symbol_1, threadgroup tint_array_wrapper_3* const tint_symbol_2) {
+void compute_main_1(thread uint* const tint_symbol_1, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol_2) {
uint const x_57 = *(tint_symbol_1);
compute_main_inner(x_57, tint_symbol_2);
return;
}
-void compute_main_inner_1(uint local_invocation_index_1_param, threadgroup tint_array_wrapper_3* const tint_symbol_3, thread uint* const tint_symbol_4) {
+void compute_main_inner_1(uint local_invocation_index_1_param, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol_3, thread uint* const tint_symbol_4) {
for(uint idx_1 = local_invocation_index_1_param; (idx_1 < 6u); idx_1 = (idx_1 + 1u)) {
uint const i = (idx_1 / 2u);
uint const i_1 = (idx_1 % 2u);
uint const i_2 = (idx_1 % 1u);
- atomic_store_explicit(&((*(tint_symbol_3)).arr[i].arr[i_1].arr[i_2]), 0u, memory_order_relaxed);
+ atomic_store_explicit(&((*(tint_symbol_3))[i][i_1][i_2]), 0u, memory_order_relaxed);
}
threadgroup_barrier(mem_flags::mem_threadgroup);
*(tint_symbol_4) = local_invocation_index_1_param;
@@ -66,7 +55,7 @@
}
kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]]) {
- threadgroup tint_array_wrapper_3 tint_symbol_5;
+ threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3> tint_symbol_5;
thread uint tint_symbol_6 = 0u;
compute_main_inner_1(local_invocation_index_1_param, &(tint_symbol_5), &(tint_symbol_6));
return;
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.glsl b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.glsl
new file mode 100644
index 0000000..598fde9
--- /dev/null
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.glsl
@@ -0,0 +1,21 @@
+#version 310 es
+
+shared uint wg[3][2][1];
+void compute_main(uint local_invocation_index) {
+ {
+ for(uint idx = local_invocation_index; (idx < 6u); idx = (idx + 1u)) {
+ uint i = (idx / 2u);
+ uint i_1 = (idx % 2u);
+ uint i_2 = (idx % 1u);
+ atomicExchange(wg[i][i_1][i_2], 0u);
+ }
+ }
+ barrier();
+ atomicExchange(wg[2][1][0], 1u);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ compute_main(gl_LocalInvocationIndex);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.hlsl b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.hlsl
new file mode 100644
index 0000000..6f993d5
--- /dev/null
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.hlsl
@@ -0,0 +1,26 @@
+groupshared uint wg[3][2][1];
+
+struct tint_symbol_1 {
+ uint local_invocation_index : SV_GroupIndex;
+};
+
+void compute_main_inner(uint local_invocation_index) {
+ {
+ [loop] for(uint idx = local_invocation_index; (idx < 6u); idx = (idx + 1u)) {
+ const uint i = (idx / 2u);
+ const uint i_1 = (idx % 2u);
+ const uint i_2 = (idx % 1u);
+ uint atomic_result = 0u;
+ InterlockedExchange(wg[i][i_1][i_2], 0u, atomic_result);
+ }
+ }
+ GroupMemoryBarrierWithGroupSync();
+ uint atomic_result_1 = 0u;
+ InterlockedExchange(wg[2][1][0], 1u, atomic_result_1);
+}
+
+[numthreads(1, 1, 1)]
+void compute_main(tint_symbol_1 tint_symbol) {
+ compute_main_inner(tint_symbol.local_invocation_index);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.msl b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.msl
new file mode 100644
index 0000000..51e5245
--- /dev/null
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
+};
+
+void compute_main_inner(uint local_invocation_index, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol) {
+ for(uint idx = local_invocation_index; (idx < 6u); idx = (idx + 1u)) {
+ uint const i = (idx / 2u);
+ uint const i_1 = (idx % 2u);
+ uint const i_2 = (idx % 1u);
+ atomic_store_explicit(&((*(tint_symbol))[i][i_1][i_2]), 0u, memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomic_store_explicit(&((*(tint_symbol))[2][1][0]), 1u, memory_order_relaxed);
+}
+
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3> tint_symbol_1;
+ compute_main_inner(local_invocation_index, &(tint_symbol_1));
+ return;
+}
+
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.spvasm b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.spvasm
new file mode 100644
index 0000000..0dbd964
--- /dev/null
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.spvasm
@@ -0,0 +1,88 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 58
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
+ OpExecutionMode %compute_main LocalSize 1 1 1
+ OpName %local_invocation_index_1 "local_invocation_index_1"
+ OpName %wg "wg"
+ OpName %compute_main_inner "compute_main_inner"
+ OpName %local_invocation_index "local_invocation_index"
+ OpName %idx "idx"
+ OpName %compute_main "compute_main"
+ OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
+ OpDecorate %_arr_uint_uint_1 ArrayStride 4
+ OpDecorate %_arr__arr_uint_uint_1_uint_2 ArrayStride 4
+ OpDecorate %_arr__arr__arr_uint_uint_1_uint_2_uint_3 ArrayStride 8
+ %uint = OpTypeInt 32 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
+ %uint_1 = OpConstant %uint 1
+%_arr_uint_uint_1 = OpTypeArray %uint %uint_1
+ %uint_2 = OpConstant %uint 2
+%_arr__arr_uint_uint_1_uint_2 = OpTypeArray %_arr_uint_uint_1 %uint_2
+ %uint_3 = OpConstant %uint 3
+%_arr__arr__arr_uint_uint_1_uint_2_uint_3 = OpTypeArray %_arr__arr_uint_uint_1_uint_2 %uint_3
+%_ptr_Workgroup__arr__arr__arr_uint_uint_1_uint_2_uint_3 = OpTypePointer Workgroup %_arr__arr__arr_uint_uint_1_uint_2_uint_3
+ %wg = OpVariable %_ptr_Workgroup__arr__arr__arr_uint_uint_1_uint_2_uint_3 Workgroup
+ %void = OpTypeVoid
+ %12 = OpTypeFunction %void %uint
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %19 = OpConstantNull %uint
+ %uint_6 = OpConstant %uint 6
+ %bool = OpTypeBool
+ %uint_0 = OpConstant %uint 0
+%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
+ %uint_264 = OpConstant %uint 264
+ %int = OpTypeInt 32 1
+ %int_2 = OpConstant %int 2
+ %int_1 = OpConstant %int 1
+ %51 = OpConstantNull %int
+ %53 = OpTypeFunction %void
+%compute_main_inner = OpFunction %void None %12
+%local_invocation_index = OpFunctionParameter %uint
+ %16 = OpLabel
+ %idx = OpVariable %_ptr_Function_uint Function %19
+ OpStore %idx %local_invocation_index
+ OpBranch %20
+ %20 = OpLabel
+ OpLoopMerge %21 %22 None
+ OpBranch %23
+ %23 = OpLabel
+ %25 = OpLoad %uint %idx
+ %27 = OpULessThan %bool %25 %uint_6
+ %24 = OpLogicalNot %bool %27
+ OpSelectionMerge %29 None
+ OpBranchConditional %24 %30 %29
+ %30 = OpLabel
+ OpBranch %21
+ %29 = OpLabel
+ %31 = OpLoad %uint %idx
+ %32 = OpUDiv %uint %31 %uint_2
+ %33 = OpLoad %uint %idx
+ %34 = OpUMod %uint %33 %uint_2
+ %35 = OpLoad %uint %idx
+ %36 = OpUMod %uint %35 %uint_1
+ %41 = OpAccessChain %_ptr_Workgroup_uint %wg %32 %34 %36
+ OpAtomicStore %41 %uint_2 %uint_0 %19
+ OpBranch %22
+ %22 = OpLabel
+ %42 = OpLoad %uint %idx
+ %43 = OpIAdd %uint %42 %uint_1
+ OpStore %idx %43
+ OpBranch %20
+ %21 = OpLabel
+ OpControlBarrier %uint_2 %uint_2 %uint_264
+ %52 = OpAccessChain %_ptr_Workgroup_uint %wg %int_2 %int_1 %51
+ OpAtomicStore %52 %uint_2 %uint_0 %uint_1
+ OpReturn
+ OpFunctionEnd
+%compute_main = OpFunction %void None %53
+ %55 = OpLabel
+ %57 = OpLoad %uint %local_invocation_index_1
+ %56 = OpFunctionCall %void %compute_main_inner %57
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.wgsl b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.wgsl
new file mode 100644
index 0000000..0a5ac8a
--- /dev/null
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.wgsl
@@ -0,0 +1,14 @@
+type A0 = atomic<u32>;
+
+type A1 = array<A0, 1>;
+
+type A2 = array<A1, 2>;
+
+type A3 = array<A2, 3>;
+
+var<workgroup> wg : A3;
+
+@compute @workgroup_size(1)
+fn compute_main() {
+ atomicStore(&(wg[2][1][0]), 1u);
+}
diff --git a/test/tint/builtins/atomicStore/array/array.spvasm.expected.msl b/test/tint/builtins/atomicStore/array/array.spvasm.expected.msl
index d2ab1ec..8ef9d39 100644
--- a/test/tint/builtins/atomicStore/array/array.spvasm.expected.msl
+++ b/test/tint/builtins/atomicStore/array/array.spvasm.expected.msl
@@ -1,15 +1,20 @@
#include <metal_stdlib>
using namespace metal;
-struct tint_array_wrapper {
- uint arr[4];
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
};
-struct tint_array_wrapper_1 {
- atomic_uint arr[4];
-};
-
-void compute_main_inner(uint local_invocation_index, threadgroup tint_array_wrapper_1* const tint_symbol) {
+void compute_main_inner(uint local_invocation_index, threadgroup tint_array<atomic_uint, 4>* const tint_symbol) {
uint idx = 0u;
idx = local_invocation_index;
while (true) {
@@ -18,27 +23,27 @@
break;
}
uint const x_26 = idx;
- atomic_store_explicit(&((*(tint_symbol)).arr[x_26]), 0u, memory_order_relaxed);
+ atomic_store_explicit(&((*(tint_symbol))[x_26]), 0u, memory_order_relaxed);
{
uint const x_33 = idx;
idx = (x_33 + 1u);
}
}
threadgroup_barrier(mem_flags::mem_threadgroup);
- atomic_store_explicit(&((*(tint_symbol)).arr[1]), 1u, memory_order_relaxed);
+ atomic_store_explicit(&((*(tint_symbol))[1]), 1u, memory_order_relaxed);
return;
}
-void compute_main_1(thread uint* const tint_symbol_1, threadgroup tint_array_wrapper_1* const tint_symbol_2) {
+void compute_main_1(thread uint* const tint_symbol_1, threadgroup tint_array<atomic_uint, 4>* const tint_symbol_2) {
uint const x_47 = *(tint_symbol_1);
compute_main_inner(x_47, tint_symbol_2);
return;
}
-void compute_main_inner_1(uint local_invocation_index_1_param, threadgroup tint_array_wrapper_1* const tint_symbol_3, thread uint* const tint_symbol_4) {
+void compute_main_inner_1(uint local_invocation_index_1_param, threadgroup tint_array<atomic_uint, 4>* const tint_symbol_3, thread uint* const tint_symbol_4) {
for(uint idx_1 = local_invocation_index_1_param; (idx_1 < 4u); idx_1 = (idx_1 + 1u)) {
uint const i = idx_1;
- atomic_store_explicit(&((*(tint_symbol_3)).arr[i]), 0u, memory_order_relaxed);
+ atomic_store_explicit(&((*(tint_symbol_3))[i]), 0u, memory_order_relaxed);
}
threadgroup_barrier(mem_flags::mem_threadgroup);
*(tint_symbol_4) = local_invocation_index_1_param;
@@ -46,7 +51,7 @@
}
kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]]) {
- threadgroup tint_array_wrapper_1 tint_symbol_5;
+ threadgroup tint_array<atomic_uint, 4> tint_symbol_5;
thread uint tint_symbol_6 = 0u;
compute_main_inner_1(local_invocation_index_1_param, &(tint_symbol_5), &(tint_symbol_6));
return;
diff --git a/test/tint/builtins/atomicStore/array/array.wgsl.expected.glsl b/test/tint/builtins/atomicStore/array/array.wgsl.expected.glsl
new file mode 100644
index 0000000..653bae6
--- /dev/null
+++ b/test/tint/builtins/atomicStore/array/array.wgsl.expected.glsl
@@ -0,0 +1,19 @@
+#version 310 es
+
+shared uint wg[4];
+void compute_main(uint local_invocation_index) {
+ {
+ for(uint idx = local_invocation_index; (idx < 4u); idx = (idx + 1u)) {
+ uint i = idx;
+ atomicExchange(wg[i], 0u);
+ }
+ }
+ barrier();
+ atomicExchange(wg[1], 1u);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ compute_main(gl_LocalInvocationIndex);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/array/array.wgsl.expected.hlsl b/test/tint/builtins/atomicStore/array/array.wgsl.expected.hlsl
new file mode 100644
index 0000000..d2ff575
--- /dev/null
+++ b/test/tint/builtins/atomicStore/array/array.wgsl.expected.hlsl
@@ -0,0 +1,24 @@
+groupshared uint wg[4];
+
+struct tint_symbol_1 {
+ uint local_invocation_index : SV_GroupIndex;
+};
+
+void compute_main_inner(uint local_invocation_index) {
+ {
+ [loop] for(uint idx = local_invocation_index; (idx < 4u); idx = (idx + 1u)) {
+ const uint i = idx;
+ uint atomic_result = 0u;
+ InterlockedExchange(wg[i], 0u, atomic_result);
+ }
+ }
+ GroupMemoryBarrierWithGroupSync();
+ uint atomic_result_1 = 0u;
+ InterlockedExchange(wg[1], 1u, atomic_result_1);
+}
+
+[numthreads(1, 1, 1)]
+void compute_main(tint_symbol_1 tint_symbol) {
+ compute_main_inner(tint_symbol.local_invocation_index);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/array/array.wgsl.expected.msl b/test/tint/builtins/atomicStore/array/array.wgsl.expected.msl
new file mode 100644
index 0000000..5f20d27
--- /dev/null
+++ b/test/tint/builtins/atomicStore/array/array.wgsl.expected.msl
@@ -0,0 +1,31 @@
+#include <metal_stdlib>
+
+using namespace metal;
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
+};
+
+void compute_main_inner(uint local_invocation_index, threadgroup tint_array<atomic_uint, 4>* const tint_symbol) {
+ for(uint idx = local_invocation_index; (idx < 4u); idx = (idx + 1u)) {
+ uint const i = idx;
+ atomic_store_explicit(&((*(tint_symbol))[i]), 0u, memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomic_store_explicit(&((*(tint_symbol))[1]), 1u, memory_order_relaxed);
+}
+
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup tint_array<atomic_uint, 4> tint_symbol_1;
+ compute_main_inner(local_invocation_index, &(tint_symbol_1));
+ return;
+}
+
diff --git a/test/tint/builtins/atomicStore/array/array.wgsl.expected.spvasm b/test/tint/builtins/atomicStore/array/array.wgsl.expected.spvasm
new file mode 100644
index 0000000..f41ddf7
--- /dev/null
+++ b/test/tint/builtins/atomicStore/array/array.wgsl.expected.spvasm
@@ -0,0 +1,76 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 48
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
+ OpExecutionMode %compute_main LocalSize 1 1 1
+ OpName %local_invocation_index_1 "local_invocation_index_1"
+ OpName %wg "wg"
+ OpName %compute_main_inner "compute_main_inner"
+ OpName %local_invocation_index "local_invocation_index"
+ OpName %idx "idx"
+ OpName %compute_main "compute_main"
+ OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
+ OpDecorate %_arr_uint_uint_4 ArrayStride 4
+ %uint = OpTypeInt 32 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
+ %uint_4 = OpConstant %uint 4
+%_arr_uint_uint_4 = OpTypeArray %uint %uint_4
+%_ptr_Workgroup__arr_uint_uint_4 = OpTypePointer Workgroup %_arr_uint_uint_4
+ %wg = OpVariable %_ptr_Workgroup__arr_uint_uint_4 Workgroup
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void %uint
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %15 = OpConstantNull %uint
+ %bool = OpTypeBool
+ %uint_2 = OpConstant %uint 2
+ %uint_0 = OpConstant %uint 0
+%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
+ %uint_1 = OpConstant %uint 1
+ %uint_264 = OpConstant %uint 264
+ %int = OpTypeInt 32 1
+ %int_1 = OpConstant %int 1
+ %43 = OpTypeFunction %void
+%compute_main_inner = OpFunction %void None %8
+%local_invocation_index = OpFunctionParameter %uint
+ %12 = OpLabel
+ %idx = OpVariable %_ptr_Function_uint Function %15
+ OpStore %idx %local_invocation_index
+ OpBranch %16
+ %16 = OpLabel
+ OpLoopMerge %17 %18 None
+ OpBranch %19
+ %19 = OpLabel
+ %21 = OpLoad %uint %idx
+ %22 = OpULessThan %bool %21 %uint_4
+ %20 = OpLogicalNot %bool %22
+ OpSelectionMerge %24 None
+ OpBranchConditional %20 %25 %24
+ %25 = OpLabel
+ OpBranch %17
+ %24 = OpLabel
+ %26 = OpLoad %uint %idx
+ %32 = OpAccessChain %_ptr_Workgroup_uint %wg %26
+ OpAtomicStore %32 %uint_2 %uint_0 %15
+ OpBranch %18
+ %18 = OpLabel
+ %33 = OpLoad %uint %idx
+ %35 = OpIAdd %uint %33 %uint_1
+ OpStore %idx %35
+ OpBranch %16
+ %17 = OpLabel
+ OpControlBarrier %uint_2 %uint_2 %uint_264
+ %42 = OpAccessChain %_ptr_Workgroup_uint %wg %int_1
+ OpAtomicStore %42 %uint_2 %uint_0 %uint_1
+ OpReturn
+ OpFunctionEnd
+%compute_main = OpFunction %void None %43
+ %45 = OpLabel
+ %47 = OpLoad %uint %local_invocation_index_1
+ %46 = OpFunctionCall %void %compute_main_inner %47
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/array/array.wgsl.expected.wgsl b/test/tint/builtins/atomicStore/array/array.wgsl.expected.wgsl
new file mode 100644
index 0000000..f6812d4
--- /dev/null
+++ b/test/tint/builtins/atomicStore/array/array.wgsl.expected.wgsl
@@ -0,0 +1,6 @@
+var<workgroup> wg : array<atomic<u32>, 4>;
+
+@compute @workgroup_size(1)
+fn compute_main() {
+ atomicStore(&(wg[1]), 1u);
+}
diff --git a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.msl b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.msl
index 896696e..943a64c 100644
--- a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.msl
+++ b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.msl
@@ -1,31 +1,20 @@
#include <metal_stdlib>
using namespace metal;
-struct tint_array_wrapper {
- uint arr[1];
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
};
-struct tint_array_wrapper_1 {
- tint_array_wrapper arr[2];
-};
-
-struct tint_array_wrapper_2 {
- tint_array_wrapper_1 arr[3];
-};
-
-struct tint_array_wrapper_5 {
- atomic_uint arr[1];
-};
-
-struct tint_array_wrapper_4 {
- tint_array_wrapper_5 arr[2];
-};
-
-struct tint_array_wrapper_3 {
- tint_array_wrapper_4 arr[3];
-};
-
-void compute_main_inner(uint local_invocation_index, threadgroup tint_array_wrapper_3* const tint_symbol) {
+void compute_main_inner(uint local_invocation_index, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol) {
uint idx = 0u;
idx = local_invocation_index;
while (true) {
@@ -36,29 +25,29 @@
uint const x_31 = idx;
uint const x_33 = idx;
uint const x_35 = idx;
- atomic_store_explicit(&((*(tint_symbol)).arr[(x_31 / 2u)].arr[(x_33 % 2u)].arr[(x_35 % 1u)]), 0u, memory_order_relaxed);
+ atomic_store_explicit(&((*(tint_symbol))[(x_31 / 2u)][(x_33 % 2u)][(x_35 % 1u)]), 0u, memory_order_relaxed);
{
uint const x_42 = idx;
idx = (x_42 + 1u);
}
}
threadgroup_barrier(mem_flags::mem_threadgroup);
- atomic_store_explicit(&((*(tint_symbol)).arr[2].arr[1].arr[0]), 1u, memory_order_relaxed);
+ atomic_store_explicit(&((*(tint_symbol))[2][1][0]), 1u, memory_order_relaxed);
return;
}
-void compute_main_1(thread uint* const tint_symbol_1, threadgroup tint_array_wrapper_3* const tint_symbol_2) {
+void compute_main_1(thread uint* const tint_symbol_1, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol_2) {
uint const x_57 = *(tint_symbol_1);
compute_main_inner(x_57, tint_symbol_2);
return;
}
-void compute_main_inner_1(uint local_invocation_index_1_param, threadgroup tint_array_wrapper_3* const tint_symbol_3, thread uint* const tint_symbol_4) {
+void compute_main_inner_1(uint local_invocation_index_1_param, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol_3, thread uint* const tint_symbol_4) {
for(uint idx_1 = local_invocation_index_1_param; (idx_1 < 6u); idx_1 = (idx_1 + 1u)) {
uint const i = (idx_1 / 2u);
uint const i_1 = (idx_1 % 2u);
uint const i_2 = (idx_1 % 1u);
- atomic_store_explicit(&((*(tint_symbol_3)).arr[i].arr[i_1].arr[i_2]), 0u, memory_order_relaxed);
+ atomic_store_explicit(&((*(tint_symbol_3))[i][i_1][i_2]), 0u, memory_order_relaxed);
}
threadgroup_barrier(mem_flags::mem_threadgroup);
*(tint_symbol_4) = local_invocation_index_1_param;
@@ -66,7 +55,7 @@
}
kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]]) {
- threadgroup tint_array_wrapper_3 tint_symbol_5;
+ threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3> tint_symbol_5;
thread uint tint_symbol_6 = 0u;
compute_main_inner_1(local_invocation_index_1_param, &(tint_symbol_5), &(tint_symbol_6));
return;
diff --git a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.glsl b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.glsl
new file mode 100644
index 0000000..598fde9
--- /dev/null
+++ b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.glsl
@@ -0,0 +1,21 @@
+#version 310 es
+
+shared uint wg[3][2][1];
+void compute_main(uint local_invocation_index) {
+ {
+ for(uint idx = local_invocation_index; (idx < 6u); idx = (idx + 1u)) {
+ uint i = (idx / 2u);
+ uint i_1 = (idx % 2u);
+ uint i_2 = (idx % 1u);
+ atomicExchange(wg[i][i_1][i_2], 0u);
+ }
+ }
+ barrier();
+ atomicExchange(wg[2][1][0], 1u);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ compute_main(gl_LocalInvocationIndex);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.hlsl b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.hlsl
new file mode 100644
index 0000000..6f993d5
--- /dev/null
+++ b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.hlsl
@@ -0,0 +1,26 @@
+groupshared uint wg[3][2][1];
+
+struct tint_symbol_1 {
+ uint local_invocation_index : SV_GroupIndex;
+};
+
+void compute_main_inner(uint local_invocation_index) {
+ {
+ [loop] for(uint idx = local_invocation_index; (idx < 6u); idx = (idx + 1u)) {
+ const uint i = (idx / 2u);
+ const uint i_1 = (idx % 2u);
+ const uint i_2 = (idx % 1u);
+ uint atomic_result = 0u;
+ InterlockedExchange(wg[i][i_1][i_2], 0u, atomic_result);
+ }
+ }
+ GroupMemoryBarrierWithGroupSync();
+ uint atomic_result_1 = 0u;
+ InterlockedExchange(wg[2][1][0], 1u, atomic_result_1);
+}
+
+[numthreads(1, 1, 1)]
+void compute_main(tint_symbol_1 tint_symbol) {
+ compute_main_inner(tint_symbol.local_invocation_index);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.msl b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.msl
new file mode 100644
index 0000000..51e5245
--- /dev/null
+++ b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
+};
+
+void compute_main_inner(uint local_invocation_index, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol) {
+ for(uint idx = local_invocation_index; (idx < 6u); idx = (idx + 1u)) {
+ uint const i = (idx / 2u);
+ uint const i_1 = (idx % 2u);
+ uint const i_2 = (idx % 1u);
+ atomic_store_explicit(&((*(tint_symbol))[i][i_1][i_2]), 0u, memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomic_store_explicit(&((*(tint_symbol))[2][1][0]), 1u, memory_order_relaxed);
+}
+
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3> tint_symbol_1;
+ compute_main_inner(local_invocation_index, &(tint_symbol_1));
+ return;
+}
+
diff --git a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.spvasm b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.spvasm
new file mode 100644
index 0000000..0dbd964
--- /dev/null
+++ b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.spvasm
@@ -0,0 +1,88 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 58
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
+ OpExecutionMode %compute_main LocalSize 1 1 1
+ OpName %local_invocation_index_1 "local_invocation_index_1"
+ OpName %wg "wg"
+ OpName %compute_main_inner "compute_main_inner"
+ OpName %local_invocation_index "local_invocation_index"
+ OpName %idx "idx"
+ OpName %compute_main "compute_main"
+ OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
+ OpDecorate %_arr_uint_uint_1 ArrayStride 4
+ OpDecorate %_arr__arr_uint_uint_1_uint_2 ArrayStride 4
+ OpDecorate %_arr__arr__arr_uint_uint_1_uint_2_uint_3 ArrayStride 8
+ %uint = OpTypeInt 32 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
+ %uint_1 = OpConstant %uint 1
+%_arr_uint_uint_1 = OpTypeArray %uint %uint_1
+ %uint_2 = OpConstant %uint 2
+%_arr__arr_uint_uint_1_uint_2 = OpTypeArray %_arr_uint_uint_1 %uint_2
+ %uint_3 = OpConstant %uint 3
+%_arr__arr__arr_uint_uint_1_uint_2_uint_3 = OpTypeArray %_arr__arr_uint_uint_1_uint_2 %uint_3
+%_ptr_Workgroup__arr__arr__arr_uint_uint_1_uint_2_uint_3 = OpTypePointer Workgroup %_arr__arr__arr_uint_uint_1_uint_2_uint_3
+ %wg = OpVariable %_ptr_Workgroup__arr__arr__arr_uint_uint_1_uint_2_uint_3 Workgroup
+ %void = OpTypeVoid
+ %12 = OpTypeFunction %void %uint
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %19 = OpConstantNull %uint
+ %uint_6 = OpConstant %uint 6
+ %bool = OpTypeBool
+ %uint_0 = OpConstant %uint 0
+%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
+ %uint_264 = OpConstant %uint 264
+ %int = OpTypeInt 32 1
+ %int_2 = OpConstant %int 2
+ %int_1 = OpConstant %int 1
+ %51 = OpConstantNull %int
+ %53 = OpTypeFunction %void
+%compute_main_inner = OpFunction %void None %12
+%local_invocation_index = OpFunctionParameter %uint
+ %16 = OpLabel
+ %idx = OpVariable %_ptr_Function_uint Function %19
+ OpStore %idx %local_invocation_index
+ OpBranch %20
+ %20 = OpLabel
+ OpLoopMerge %21 %22 None
+ OpBranch %23
+ %23 = OpLabel
+ %25 = OpLoad %uint %idx
+ %27 = OpULessThan %bool %25 %uint_6
+ %24 = OpLogicalNot %bool %27
+ OpSelectionMerge %29 None
+ OpBranchConditional %24 %30 %29
+ %30 = OpLabel
+ OpBranch %21
+ %29 = OpLabel
+ %31 = OpLoad %uint %idx
+ %32 = OpUDiv %uint %31 %uint_2
+ %33 = OpLoad %uint %idx
+ %34 = OpUMod %uint %33 %uint_2
+ %35 = OpLoad %uint %idx
+ %36 = OpUMod %uint %35 %uint_1
+ %41 = OpAccessChain %_ptr_Workgroup_uint %wg %32 %34 %36
+ OpAtomicStore %41 %uint_2 %uint_0 %19
+ OpBranch %22
+ %22 = OpLabel
+ %42 = OpLoad %uint %idx
+ %43 = OpIAdd %uint %42 %uint_1
+ OpStore %idx %43
+ OpBranch %20
+ %21 = OpLabel
+ OpControlBarrier %uint_2 %uint_2 %uint_264
+ %52 = OpAccessChain %_ptr_Workgroup_uint %wg %int_2 %int_1 %51
+ OpAtomicStore %52 %uint_2 %uint_0 %uint_1
+ OpReturn
+ OpFunctionEnd
+%compute_main = OpFunction %void None %53
+ %55 = OpLabel
+ %57 = OpLoad %uint %local_invocation_index_1
+ %56 = OpFunctionCall %void %compute_main_inner %57
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.wgsl b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.wgsl
new file mode 100644
index 0000000..3ca55977
--- /dev/null
+++ b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.wgsl
@@ -0,0 +1,6 @@
+var<workgroup> wg : array<array<array<atomic<u32>, 1>, 2>, 3>;
+
+@compute @workgroup_size(1)
+fn compute_main() {
+ atomicStore(&(wg[2][1][0]), 1u);
+}
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.msl b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.msl
index 5360fda..f4fd526 100644
--- a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.msl
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.msl
@@ -1,6 +1,19 @@
#include <metal_stdlib>
using namespace metal;
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
+};
+
struct S_atomic {
int x;
atomic_uint a;
@@ -13,15 +26,7 @@
uint y;
};
-struct tint_array_wrapper {
- S arr[10];
-};
-
-struct tint_array_wrapper_1 {
- S_atomic arr[10];
-};
-
-void compute_main_inner(uint local_invocation_index, threadgroup tint_array_wrapper_1* const tint_symbol) {
+void compute_main_inner(uint local_invocation_index, threadgroup tint_array<S_atomic, 10>* const tint_symbol) {
uint idx = 0u;
idx = local_invocation_index;
while (true) {
@@ -30,31 +35,31 @@
break;
}
uint const x_28 = idx;
- (*(tint_symbol)).arr[x_28].x = 0;
- atomic_store_explicit(&((*(tint_symbol)).arr[x_28].a), 0u, memory_order_relaxed);
- (*(tint_symbol)).arr[x_28].y = 0u;
+ (*(tint_symbol))[x_28].x = 0;
+ atomic_store_explicit(&((*(tint_symbol))[x_28].a), 0u, memory_order_relaxed);
+ (*(tint_symbol))[x_28].y = 0u;
{
uint const x_41 = idx;
idx = (x_41 + 1u);
}
}
threadgroup_barrier(mem_flags::mem_threadgroup);
- atomic_store_explicit(&((*(tint_symbol)).arr[4].a), 1u, memory_order_relaxed);
+ atomic_store_explicit(&((*(tint_symbol))[4].a), 1u, memory_order_relaxed);
return;
}
-void compute_main_1(thread uint* const tint_symbol_1, threadgroup tint_array_wrapper_1* const tint_symbol_2) {
+void compute_main_1(thread uint* const tint_symbol_1, threadgroup tint_array<S_atomic, 10>* const tint_symbol_2) {
uint const x_53 = *(tint_symbol_1);
compute_main_inner(x_53, tint_symbol_2);
return;
}
-void compute_main_inner_1(uint local_invocation_index_1_param, threadgroup tint_array_wrapper_1* const tint_symbol_3, thread uint* const tint_symbol_4) {
+void compute_main_inner_1(uint local_invocation_index_1_param, threadgroup tint_array<S_atomic, 10>* const tint_symbol_3, thread uint* const tint_symbol_4) {
for(uint idx_1 = local_invocation_index_1_param; (idx_1 < 10u); idx_1 = (idx_1 + 1u)) {
uint const i = idx_1;
- (*(tint_symbol_3)).arr[i].x = 0;
- atomic_store_explicit(&((*(tint_symbol_3)).arr[i].a), 0u, memory_order_relaxed);
- (*(tint_symbol_3)).arr[i].y = 0u;
+ (*(tint_symbol_3))[i].x = 0;
+ atomic_store_explicit(&((*(tint_symbol_3))[i].a), 0u, memory_order_relaxed);
+ (*(tint_symbol_3))[i].y = 0u;
}
threadgroup_barrier(mem_flags::mem_threadgroup);
*(tint_symbol_4) = local_invocation_index_1_param;
@@ -62,7 +67,7 @@
}
kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]]) {
- threadgroup tint_array_wrapper_1 tint_symbol_5;
+ threadgroup tint_array<S_atomic, 10> tint_symbol_5;
thread uint tint_symbol_6 = 0u;
compute_main_inner_1(local_invocation_index_1_param, &(tint_symbol_5), &(tint_symbol_6));
return;
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.glsl b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.glsl
new file mode 100644
index 0000000..bd0a3ba
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.glsl
@@ -0,0 +1,27 @@
+#version 310 es
+
+struct S {
+ int x;
+ uint a;
+ uint y;
+};
+
+shared S wg[10];
+void compute_main(uint local_invocation_index) {
+ {
+ for(uint idx = local_invocation_index; (idx < 10u); idx = (idx + 1u)) {
+ uint i = idx;
+ wg[i].x = 0;
+ atomicExchange(wg[i].a, 0u);
+ wg[i].y = 0u;
+ }
+ }
+ barrier();
+ atomicExchange(wg[4].a, 1u);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ compute_main(gl_LocalInvocationIndex);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.hlsl b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.hlsl
new file mode 100644
index 0000000..4642386
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.hlsl
@@ -0,0 +1,32 @@
+struct S {
+ int x;
+ uint a;
+ uint y;
+};
+
+groupshared S wg[10];
+
+struct tint_symbol_1 {
+ uint local_invocation_index : SV_GroupIndex;
+};
+
+void compute_main_inner(uint local_invocation_index) {
+ {
+ [loop] for(uint idx = local_invocation_index; (idx < 10u); idx = (idx + 1u)) {
+ const uint i = idx;
+ wg[i].x = 0;
+ uint atomic_result = 0u;
+ InterlockedExchange(wg[i].a, 0u, atomic_result);
+ wg[i].y = 0u;
+ }
+ }
+ GroupMemoryBarrierWithGroupSync();
+ uint atomic_result_1 = 0u;
+ InterlockedExchange(wg[4].a, 1u, atomic_result_1);
+}
+
+[numthreads(1, 1, 1)]
+void compute_main(tint_symbol_1 tint_symbol) {
+ compute_main_inner(tint_symbol.local_invocation_index);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.msl b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.msl
new file mode 100644
index 0000000..978edb1
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.msl
@@ -0,0 +1,39 @@
+#include <metal_stdlib>
+
+using namespace metal;
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
+};
+
+struct S {
+ int x;
+ atomic_uint a;
+ uint y;
+};
+
+void compute_main_inner(uint local_invocation_index, threadgroup tint_array<S, 10>* const tint_symbol) {
+ for(uint idx = local_invocation_index; (idx < 10u); idx = (idx + 1u)) {
+ uint const i = idx;
+ (*(tint_symbol))[i].x = 0;
+ atomic_store_explicit(&((*(tint_symbol))[i].a), 0u, memory_order_relaxed);
+ (*(tint_symbol))[i].y = 0u;
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomic_store_explicit(&((*(tint_symbol))[4].a), 1u, memory_order_relaxed);
+}
+
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup tint_array<S, 10> tint_symbol_1;
+ compute_main_inner(local_invocation_index, &(tint_symbol_1));
+ return;
+}
+
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.spvasm b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.spvasm
new file mode 100644
index 0000000..b9e0fed
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.spvasm
@@ -0,0 +1,91 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 54
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
+ OpExecutionMode %compute_main LocalSize 1 1 1
+ OpName %local_invocation_index_1 "local_invocation_index_1"
+ OpName %S "S"
+ OpMemberName %S 0 "x"
+ OpMemberName %S 1 "a"
+ OpMemberName %S 2 "y"
+ OpName %wg "wg"
+ OpName %compute_main_inner "compute_main_inner"
+ OpName %local_invocation_index "local_invocation_index"
+ OpName %idx "idx"
+ OpName %compute_main "compute_main"
+ OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
+ OpMemberDecorate %S 0 Offset 0
+ OpMemberDecorate %S 1 Offset 4
+ OpMemberDecorate %S 2 Offset 8
+ OpDecorate %_arr_S_uint_10 ArrayStride 12
+ %uint = OpTypeInt 32 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
+ %int = OpTypeInt 32 1
+ %S = OpTypeStruct %int %uint %uint
+ %uint_10 = OpConstant %uint 10
+%_arr_S_uint_10 = OpTypeArray %S %uint_10
+%_ptr_Workgroup__arr_S_uint_10 = OpTypePointer Workgroup %_arr_S_uint_10
+ %wg = OpVariable %_ptr_Workgroup__arr_S_uint_10 Workgroup
+ %void = OpTypeVoid
+ %10 = OpTypeFunction %void %uint
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %17 = OpConstantNull %uint
+ %bool = OpTypeBool
+ %uint_0 = OpConstant %uint 0
+%_ptr_Workgroup_int = OpTypePointer Workgroup %int
+ %32 = OpConstantNull %int
+ %uint_2 = OpConstant %uint 2
+ %uint_1 = OpConstant %uint 1
+%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
+%_ptr_Workgroup_uint_0 = OpTypePointer Workgroup %uint
+ %uint_264 = OpConstant %uint 264
+ %int_4 = OpConstant %int 4
+ %49 = OpTypeFunction %void
+%compute_main_inner = OpFunction %void None %10
+%local_invocation_index = OpFunctionParameter %uint
+ %14 = OpLabel
+ %idx = OpVariable %_ptr_Function_uint Function %17
+ OpStore %idx %local_invocation_index
+ OpBranch %18
+ %18 = OpLabel
+ OpLoopMerge %19 %20 None
+ OpBranch %21
+ %21 = OpLabel
+ %23 = OpLoad %uint %idx
+ %24 = OpULessThan %bool %23 %uint_10
+ %22 = OpLogicalNot %bool %24
+ OpSelectionMerge %26 None
+ OpBranchConditional %22 %27 %26
+ %27 = OpLabel
+ OpBranch %19
+ %26 = OpLabel
+ %28 = OpLoad %uint %idx
+ %31 = OpAccessChain %_ptr_Workgroup_int %wg %28 %uint_0
+ OpStore %31 %32
+ %38 = OpAccessChain %_ptr_Workgroup_uint %wg %28 %uint_1
+ OpAtomicStore %38 %uint_2 %uint_0 %17
+ %40 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %28 %uint_2
+ OpStore %40 %17
+ OpBranch %20
+ %20 = OpLabel
+ %41 = OpLoad %uint %idx
+ %42 = OpIAdd %uint %41 %uint_1
+ OpStore %idx %42
+ OpBranch %18
+ %19 = OpLabel
+ OpControlBarrier %uint_2 %uint_2 %uint_264
+ %48 = OpAccessChain %_ptr_Workgroup_uint %wg %int_4 %uint_1
+ OpAtomicStore %48 %uint_2 %uint_0 %uint_1
+ OpReturn
+ OpFunctionEnd
+%compute_main = OpFunction %void None %49
+ %51 = OpLabel
+ %53 = OpLoad %uint %local_invocation_index_1
+ %52 = OpFunctionCall %void %compute_main_inner %53
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.wgsl b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.wgsl
new file mode 100644
index 0000000..1def9bd
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.wgsl
@@ -0,0 +1,12 @@
+struct S {
+ x : i32,
+ a : atomic<u32>,
+ y : u32,
+}
+
+var<workgroup> wg : array<S, 10>;
+
+@compute @workgroup_size(1)
+fn compute_main() {
+ atomicStore(&(wg[4].a), 1u);
+}
diff --git a/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.glsl b/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.glsl
new file mode 100644
index 0000000..d3a4b83
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.glsl
@@ -0,0 +1,25 @@
+#version 310 es
+
+struct S {
+ int x;
+ uint a;
+ uint b;
+};
+
+shared S wg;
+void compute_main(uint local_invocation_index) {
+ {
+ wg.x = 0;
+ atomicExchange(wg.a, 0u);
+ atomicExchange(wg.b, 0u);
+ }
+ barrier();
+ atomicExchange(wg.a, 1u);
+ atomicExchange(wg.b, 2u);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ compute_main(gl_LocalInvocationIndex);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.hlsl b/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.hlsl
new file mode 100644
index 0000000..35b428f
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.hlsl
@@ -0,0 +1,32 @@
+struct S {
+ int x;
+ uint a;
+ uint b;
+};
+
+groupshared S wg;
+
+struct tint_symbol_1 {
+ uint local_invocation_index : SV_GroupIndex;
+};
+
+void compute_main_inner(uint local_invocation_index) {
+ {
+ wg.x = 0;
+ uint atomic_result = 0u;
+ InterlockedExchange(wg.a, 0u, atomic_result);
+ uint atomic_result_1 = 0u;
+ InterlockedExchange(wg.b, 0u, atomic_result_1);
+ }
+ GroupMemoryBarrierWithGroupSync();
+ uint atomic_result_2 = 0u;
+ InterlockedExchange(wg.a, 1u, atomic_result_2);
+ uint atomic_result_3 = 0u;
+ InterlockedExchange(wg.b, 2u, atomic_result_3);
+}
+
+[numthreads(1, 1, 1)]
+void compute_main(tint_symbol_1 tint_symbol) {
+ compute_main_inner(tint_symbol.local_invocation_index);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.msl b/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.msl
new file mode 100644
index 0000000..3ea40fa
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.msl
@@ -0,0 +1,26 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct S {
+ int x;
+ atomic_uint a;
+ atomic_uint b;
+};
+
+void compute_main_inner(uint local_invocation_index, threadgroup S* const tint_symbol) {
+ {
+ (*(tint_symbol)).x = 0;
+ atomic_store_explicit(&((*(tint_symbol)).a), 0u, memory_order_relaxed);
+ atomic_store_explicit(&((*(tint_symbol)).b), 0u, memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomic_store_explicit(&((*(tint_symbol)).a), 1u, memory_order_relaxed);
+ atomic_store_explicit(&((*(tint_symbol)).b), 2u, memory_order_relaxed);
+}
+
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup S tint_symbol_1;
+ compute_main_inner(local_invocation_index, &(tint_symbol_1));
+ return;
+}
+
diff --git a/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.spvasm b/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.spvasm
new file mode 100644
index 0000000..f61269c
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.spvasm
@@ -0,0 +1,62 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 40
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
+ OpExecutionMode %compute_main LocalSize 1 1 1
+ OpName %local_invocation_index_1 "local_invocation_index_1"
+ OpName %S "S"
+ OpMemberName %S 0 "x"
+ OpMemberName %S 1 "a"
+ OpMemberName %S 2 "b"
+ OpName %wg "wg"
+ OpName %compute_main_inner "compute_main_inner"
+ OpName %local_invocation_index "local_invocation_index"
+ OpName %compute_main "compute_main"
+ OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
+ OpMemberDecorate %S 0 Offset 0
+ OpMemberDecorate %S 1 Offset 4
+ OpMemberDecorate %S 2 Offset 8
+ %uint = OpTypeInt 32 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
+ %int = OpTypeInt 32 1
+ %S = OpTypeStruct %int %uint %uint
+%_ptr_Workgroup_S = OpTypePointer Workgroup %S
+ %wg = OpVariable %_ptr_Workgroup_S Workgroup
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void %uint
+ %uint_0 = OpConstant %uint 0
+%_ptr_Workgroup_int = OpTypePointer Workgroup %int
+ %16 = OpConstantNull %int
+ %uint_2 = OpConstant %uint 2
+ %uint_1 = OpConstant %uint 1
+%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
+ %23 = OpConstantNull %uint
+ %uint_264 = OpConstant %uint 264
+ %35 = OpTypeFunction %void
+%compute_main_inner = OpFunction %void None %8
+%local_invocation_index = OpFunctionParameter %uint
+ %12 = OpLabel
+ %15 = OpAccessChain %_ptr_Workgroup_int %wg %uint_0
+ OpStore %15 %16
+ %22 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_1
+ OpAtomicStore %22 %uint_2 %uint_0 %23
+ %26 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_2
+ OpAtomicStore %26 %uint_2 %uint_0 %23
+ OpControlBarrier %uint_2 %uint_2 %uint_264
+ %31 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_1
+ OpAtomicStore %31 %uint_2 %uint_0 %uint_1
+ %34 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_2
+ OpAtomicStore %34 %uint_2 %uint_0 %uint_2
+ OpReturn
+ OpFunctionEnd
+%compute_main = OpFunction %void None %35
+ %37 = OpLabel
+ %39 = OpLoad %uint %local_invocation_index_1
+ %38 = OpFunctionCall %void %compute_main_inner %39
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.wgsl b/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.wgsl
new file mode 100644
index 0000000..1d25d8a
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.wgsl
@@ -0,0 +1,13 @@
+struct S {
+ x : i32,
+ a : atomic<u32>,
+ b : atomic<u32>,
+}
+
+var<workgroup> wg : S;
+
+@compute @workgroup_size(1)
+fn compute_main() {
+ atomicStore(&(wg.a), 1u);
+ atomicStore(&(wg.b), 2u);
+}
diff --git a/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.glsl b/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.glsl
new file mode 100644
index 0000000..39f13a5
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.glsl
@@ -0,0 +1,24 @@
+#version 310 es
+
+struct S {
+ int x;
+ uint a;
+ uint y;
+};
+
+shared S wg;
+void compute_main(uint local_invocation_index) {
+ {
+ wg.x = 0;
+ atomicExchange(wg.a, 0u);
+ wg.y = 0u;
+ }
+ barrier();
+ atomicExchange(wg.a, 1u);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ compute_main(gl_LocalInvocationIndex);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.hlsl b/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.hlsl
new file mode 100644
index 0000000..fb93daa
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.hlsl
@@ -0,0 +1,29 @@
+struct S {
+ int x;
+ uint a;
+ uint y;
+};
+
+groupshared S wg;
+
+struct tint_symbol_1 {
+ uint local_invocation_index : SV_GroupIndex;
+};
+
+void compute_main_inner(uint local_invocation_index) {
+ {
+ wg.x = 0;
+ uint atomic_result = 0u;
+ InterlockedExchange(wg.a, 0u, atomic_result);
+ wg.y = 0u;
+ }
+ GroupMemoryBarrierWithGroupSync();
+ uint atomic_result_1 = 0u;
+ InterlockedExchange(wg.a, 1u, atomic_result_1);
+}
+
+[numthreads(1, 1, 1)]
+void compute_main(tint_symbol_1 tint_symbol) {
+ compute_main_inner(tint_symbol.local_invocation_index);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.msl b/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.msl
new file mode 100644
index 0000000..ccec811b
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.msl
@@ -0,0 +1,25 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct S {
+ int x;
+ atomic_uint a;
+ uint y;
+};
+
+void compute_main_inner(uint local_invocation_index, threadgroup S* const tint_symbol) {
+ {
+ (*(tint_symbol)).x = 0;
+ atomic_store_explicit(&((*(tint_symbol)).a), 0u, memory_order_relaxed);
+ (*(tint_symbol)).y = 0u;
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomic_store_explicit(&((*(tint_symbol)).a), 1u, memory_order_relaxed);
+}
+
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup S tint_symbol_1;
+ compute_main_inner(local_invocation_index, &(tint_symbol_1));
+ return;
+}
+
diff --git a/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.spvasm b/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.spvasm
new file mode 100644
index 0000000..acad988
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.spvasm
@@ -0,0 +1,61 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 36
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
+ OpExecutionMode %compute_main LocalSize 1 1 1
+ OpName %local_invocation_index_1 "local_invocation_index_1"
+ OpName %S "S"
+ OpMemberName %S 0 "x"
+ OpMemberName %S 1 "a"
+ OpMemberName %S 2 "y"
+ OpName %wg "wg"
+ OpName %compute_main_inner "compute_main_inner"
+ OpName %local_invocation_index "local_invocation_index"
+ OpName %compute_main "compute_main"
+ OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
+ OpMemberDecorate %S 0 Offset 0
+ OpMemberDecorate %S 1 Offset 4
+ OpMemberDecorate %S 2 Offset 8
+ %uint = OpTypeInt 32 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
+ %int = OpTypeInt 32 1
+ %S = OpTypeStruct %int %uint %uint
+%_ptr_Workgroup_S = OpTypePointer Workgroup %S
+ %wg = OpVariable %_ptr_Workgroup_S Workgroup
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void %uint
+ %uint_0 = OpConstant %uint 0
+%_ptr_Workgroup_int = OpTypePointer Workgroup %int
+ %16 = OpConstantNull %int
+ %uint_2 = OpConstant %uint 2
+ %uint_1 = OpConstant %uint 1
+%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
+ %23 = OpConstantNull %uint
+%_ptr_Workgroup_uint_0 = OpTypePointer Workgroup %uint
+ %uint_264 = OpConstant %uint 264
+ %31 = OpTypeFunction %void
+%compute_main_inner = OpFunction %void None %8
+%local_invocation_index = OpFunctionParameter %uint
+ %12 = OpLabel
+ %15 = OpAccessChain %_ptr_Workgroup_int %wg %uint_0
+ OpStore %15 %16
+ %22 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_1
+ OpAtomicStore %22 %uint_2 %uint_0 %23
+ %25 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %uint_2
+ OpStore %25 %23
+ OpControlBarrier %uint_2 %uint_2 %uint_264
+ %30 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_1
+ OpAtomicStore %30 %uint_2 %uint_0 %uint_1
+ OpReturn
+ OpFunctionEnd
+%compute_main = OpFunction %void None %31
+ %33 = OpLabel
+ %35 = OpLoad %uint %local_invocation_index_1
+ %34 = OpFunctionCall %void %compute_main_inner %35
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.wgsl b/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.wgsl
new file mode 100644
index 0000000..164ad73
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.wgsl
@@ -0,0 +1,12 @@
+struct S {
+ x : i32,
+ a : atomic<u32>,
+ y : u32,
+}
+
+var<workgroup> wg : S;
+
+@compute @workgroup_size(1)
+fn compute_main() {
+ atomicStore(&(wg.a), 1u);
+}
diff --git a/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.glsl b/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.glsl
new file mode 100644
index 0000000..10f2103
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.glsl
@@ -0,0 +1,46 @@
+#version 310 es
+
+struct S0 {
+ int x;
+ uint a;
+ int y;
+ int z;
+};
+
+struct S1 {
+ int x;
+ S0 a;
+ int y;
+ int z;
+};
+
+struct S2 {
+ int x;
+ int y;
+ int z;
+ S1 a;
+};
+
+shared S2 wg;
+void compute_main(uint local_invocation_index) {
+ {
+ wg.x = 0;
+ wg.y = 0;
+ wg.z = 0;
+ wg.a.x = 0;
+ wg.a.a.x = 0;
+ atomicExchange(wg.a.a.a, 0u);
+ wg.a.a.y = 0;
+ wg.a.a.z = 0;
+ wg.a.y = 0;
+ wg.a.z = 0;
+ }
+ barrier();
+ atomicExchange(wg.a.a.a, 1u);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ compute_main(gl_LocalInvocationIndex);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.hlsl b/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.hlsl
new file mode 100644
index 0000000..4ceb2ff
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.hlsl
@@ -0,0 +1,49 @@
+struct S0 {
+ int x;
+ uint a;
+ int y;
+ int z;
+};
+struct S1 {
+ int x;
+ S0 a;
+ int y;
+ int z;
+};
+struct S2 {
+ int x;
+ int y;
+ int z;
+ S1 a;
+};
+
+groupshared S2 wg;
+
+struct tint_symbol_1 {
+ uint local_invocation_index : SV_GroupIndex;
+};
+
+void compute_main_inner(uint local_invocation_index) {
+ {
+ wg.x = 0;
+ wg.y = 0;
+ wg.z = 0;
+ wg.a.x = 0;
+ wg.a.a.x = 0;
+ uint atomic_result = 0u;
+ InterlockedExchange(wg.a.a.a, 0u, atomic_result);
+ wg.a.a.y = 0;
+ wg.a.a.z = 0;
+ wg.a.y = 0;
+ wg.a.z = 0;
+ }
+ GroupMemoryBarrierWithGroupSync();
+ uint atomic_result_1 = 0u;
+ InterlockedExchange(wg.a.a.a, 1u, atomic_result_1);
+}
+
+[numthreads(1, 1, 1)]
+void compute_main(tint_symbol_1 tint_symbol) {
+ compute_main_inner(tint_symbol.local_invocation_index);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.msl b/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.msl
new file mode 100644
index 0000000..dbe7cc0
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.msl
@@ -0,0 +1,47 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct S0 {
+ int x;
+ atomic_uint a;
+ int y;
+ int z;
+};
+
+struct S1 {
+ int x;
+ S0 a;
+ int y;
+ int z;
+};
+
+struct S2 {
+ int x;
+ int y;
+ int z;
+ S1 a;
+};
+
+void compute_main_inner(uint local_invocation_index, threadgroup S2* const tint_symbol) {
+ {
+ (*(tint_symbol)).x = 0;
+ (*(tint_symbol)).y = 0;
+ (*(tint_symbol)).z = 0;
+ (*(tint_symbol)).a.x = 0;
+ (*(tint_symbol)).a.a.x = 0;
+ atomic_store_explicit(&((*(tint_symbol)).a.a.a), 0u, memory_order_relaxed);
+ (*(tint_symbol)).a.a.y = 0;
+ (*(tint_symbol)).a.a.z = 0;
+ (*(tint_symbol)).a.y = 0;
+ (*(tint_symbol)).a.z = 0;
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomic_store_explicit(&((*(tint_symbol)).a.a.a), 1u, memory_order_relaxed);
+}
+
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup S2 tint_symbol_1;
+ compute_main_inner(local_invocation_index, &(tint_symbol_1));
+ return;
+}
+
diff --git a/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.spvasm b/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.spvasm
new file mode 100644
index 0000000..a8aaff3
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.spvasm
@@ -0,0 +1,97 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 45
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
+ OpExecutionMode %compute_main LocalSize 1 1 1
+ OpName %local_invocation_index_1 "local_invocation_index_1"
+ OpName %S2 "S2"
+ OpMemberName %S2 0 "x"
+ OpMemberName %S2 1 "y"
+ OpMemberName %S2 2 "z"
+ OpMemberName %S2 3 "a"
+ OpName %S1 "S1"
+ OpMemberName %S1 0 "x"
+ OpMemberName %S1 1 "a"
+ OpName %S0 "S0"
+ OpMemberName %S0 0 "x"
+ OpMemberName %S0 1 "a"
+ OpMemberName %S0 2 "y"
+ OpMemberName %S0 3 "z"
+ OpMemberName %S1 2 "y"
+ OpMemberName %S1 3 "z"
+ OpName %wg "wg"
+ OpName %compute_main_inner "compute_main_inner"
+ OpName %local_invocation_index "local_invocation_index"
+ OpName %compute_main "compute_main"
+ OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
+ OpMemberDecorate %S2 0 Offset 0
+ OpMemberDecorate %S2 1 Offset 4
+ OpMemberDecorate %S2 2 Offset 8
+ OpMemberDecorate %S2 3 Offset 12
+ OpMemberDecorate %S1 0 Offset 0
+ OpMemberDecorate %S1 1 Offset 4
+ OpMemberDecorate %S0 0 Offset 0
+ OpMemberDecorate %S0 1 Offset 4
+ OpMemberDecorate %S0 2 Offset 8
+ OpMemberDecorate %S0 3 Offset 12
+ OpMemberDecorate %S1 2 Offset 20
+ OpMemberDecorate %S1 3 Offset 24
+ %uint = OpTypeInt 32 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
+ %int = OpTypeInt 32 1
+ %S0 = OpTypeStruct %int %uint %int %int
+ %S1 = OpTypeStruct %int %S0 %int %int
+ %S2 = OpTypeStruct %int %int %int %S1
+%_ptr_Workgroup_S2 = OpTypePointer Workgroup %S2
+ %wg = OpVariable %_ptr_Workgroup_S2 Workgroup
+ %void = OpTypeVoid
+ %10 = OpTypeFunction %void %uint
+ %uint_0 = OpConstant %uint 0
+%_ptr_Workgroup_int = OpTypePointer Workgroup %int
+ %18 = OpConstantNull %int
+ %uint_1 = OpConstant %uint 1
+ %uint_2 = OpConstant %uint 2
+ %uint_3 = OpConstant %uint 3
+%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
+ %30 = OpConstantNull %uint
+ %uint_264 = OpConstant %uint 264
+ %40 = OpTypeFunction %void
+%compute_main_inner = OpFunction %void None %10
+%local_invocation_index = OpFunctionParameter %uint
+ %14 = OpLabel
+ %17 = OpAccessChain %_ptr_Workgroup_int %wg %uint_0
+ OpStore %17 %18
+ %20 = OpAccessChain %_ptr_Workgroup_int %wg %uint_1
+ OpStore %20 %18
+ %22 = OpAccessChain %_ptr_Workgroup_int %wg %uint_2
+ OpStore %22 %18
+ %24 = OpAccessChain %_ptr_Workgroup_int %wg %uint_3 %uint_0
+ OpStore %24 %18
+ %25 = OpAccessChain %_ptr_Workgroup_int %wg %uint_3 %uint_1 %uint_0
+ OpStore %25 %18
+ %29 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_3 %uint_1 %uint_1
+ OpAtomicStore %29 %uint_2 %uint_0 %30
+ %31 = OpAccessChain %_ptr_Workgroup_int %wg %uint_3 %uint_1 %uint_2
+ OpStore %31 %18
+ %32 = OpAccessChain %_ptr_Workgroup_int %wg %uint_3 %uint_1 %uint_3
+ OpStore %32 %18
+ %33 = OpAccessChain %_ptr_Workgroup_int %wg %uint_3 %uint_2
+ OpStore %33 %18
+ %34 = OpAccessChain %_ptr_Workgroup_int %wg %uint_3 %uint_3
+ OpStore %34 %18
+ OpControlBarrier %uint_2 %uint_2 %uint_264
+ %39 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_3 %uint_1 %uint_1
+ OpAtomicStore %39 %uint_2 %uint_0 %uint_1
+ OpReturn
+ OpFunctionEnd
+%compute_main = OpFunction %void None %40
+ %42 = OpLabel
+ %44 = OpLoad %uint %local_invocation_index_1
+ %43 = OpFunctionCall %void %compute_main_inner %44
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.wgsl b/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.wgsl
new file mode 100644
index 0000000..6a9bdac
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.wgsl
@@ -0,0 +1,27 @@
+struct S0 {
+ x : i32,
+ a : atomic<u32>,
+ y : i32,
+ z : i32,
+}
+
+struct S1 {
+ x : i32,
+ a : S0,
+ y : i32,
+ z : i32,
+}
+
+struct S2 {
+ x : i32,
+ y : i32,
+ z : i32,
+ a : S1,
+}
+
+var<workgroup> wg : S2;
+
+@compute @workgroup_size(1)
+fn compute_main() {
+ atomicStore(&(wg.a.a.a), 1u);
+}
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.msl b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.msl
index 089c011..69d565e 100644
--- a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.msl
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.msl
@@ -1,23 +1,28 @@
#include <metal_stdlib>
using namespace metal;
-struct tint_array_wrapper {
- uint arr[10];
-};
-struct tint_array_wrapper_1 {
- atomic_uint arr[10];
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
};
struct S_atomic {
int x;
- tint_array_wrapper_1 a;
+ tint_array<atomic_uint, 10> a;
uint y;
};
struct S {
int x;
- tint_array_wrapper a;
+ tint_array<uint, 10> a;
uint y;
};
@@ -32,14 +37,14 @@
break;
}
uint const x_35 = idx;
- atomic_store_explicit(&((*(tint_symbol)).a.arr[x_35]), 0u, memory_order_relaxed);
+ atomic_store_explicit(&((*(tint_symbol)).a[x_35]), 0u, memory_order_relaxed);
{
uint const x_41 = idx;
idx = (x_41 + 1u);
}
}
threadgroup_barrier(mem_flags::mem_threadgroup);
- atomic_store_explicit(&((*(tint_symbol)).a.arr[4]), 1u, memory_order_relaxed);
+ atomic_store_explicit(&((*(tint_symbol)).a[4]), 1u, memory_order_relaxed);
return;
}
@@ -56,7 +61,7 @@
}
for(uint idx_1 = local_invocation_index_1_param; (idx_1 < 10u); idx_1 = (idx_1 + 1u)) {
uint const i = idx_1;
- atomic_store_explicit(&((*(tint_symbol_3)).a.arr[i]), 0u, memory_order_relaxed);
+ atomic_store_explicit(&((*(tint_symbol_3)).a[i]), 0u, memory_order_relaxed);
}
threadgroup_barrier(mem_flags::mem_threadgroup);
*(tint_symbol_4) = local_invocation_index_1_param;
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.glsl b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.glsl
new file mode 100644
index 0000000..287b69b
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.glsl
@@ -0,0 +1,29 @@
+#version 310 es
+
+struct S {
+ int x;
+ uint a[10];
+ uint y;
+};
+
+shared S wg;
+void compute_main(uint local_invocation_index) {
+ {
+ wg.x = 0;
+ wg.y = 0u;
+ }
+ {
+ for(uint idx = local_invocation_index; (idx < 10u); idx = (idx + 1u)) {
+ uint i = idx;
+ atomicExchange(wg.a[i], 0u);
+ }
+ }
+ barrier();
+ atomicExchange(wg.a[4], 1u);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ compute_main(gl_LocalInvocationIndex);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.hlsl b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.hlsl
new file mode 100644
index 0000000..855c198
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.hlsl
@@ -0,0 +1,34 @@
+struct S {
+ int x;
+ uint a[10];
+ uint y;
+};
+
+groupshared S wg;
+
+struct tint_symbol_1 {
+ uint local_invocation_index : SV_GroupIndex;
+};
+
+void compute_main_inner(uint local_invocation_index) {
+ {
+ wg.x = 0;
+ wg.y = 0u;
+ }
+ {
+ [loop] for(uint idx = local_invocation_index; (idx < 10u); idx = (idx + 1u)) {
+ const uint i = idx;
+ uint atomic_result = 0u;
+ InterlockedExchange(wg.a[i], 0u, atomic_result);
+ }
+ }
+ GroupMemoryBarrierWithGroupSync();
+ uint atomic_result_1 = 0u;
+ InterlockedExchange(wg.a[4], 1u, atomic_result_1);
+}
+
+[numthreads(1, 1, 1)]
+void compute_main(tint_symbol_1 tint_symbol) {
+ compute_main_inner(tint_symbol.local_invocation_index);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.msl b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.msl
new file mode 100644
index 0000000..00fa7d5
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.msl
@@ -0,0 +1,41 @@
+#include <metal_stdlib>
+
+using namespace metal;
+
+template<typename T, size_t N>
+struct tint_array {
+ const constant T& operator[](size_t i) const constant { return elements[i]; }
+ device T& operator[](size_t i) device { return elements[i]; }
+ const device T& operator[](size_t i) const device { return elements[i]; }
+ thread T& operator[](size_t i) thread { return elements[i]; }
+ const thread T& operator[](size_t i) const thread { return elements[i]; }
+ threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+ const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+ T elements[N];
+};
+
+struct S {
+ int x;
+ tint_array<atomic_uint, 10> a;
+ uint y;
+};
+
+void compute_main_inner(uint local_invocation_index, threadgroup S* const tint_symbol) {
+ {
+ (*(tint_symbol)).x = 0;
+ (*(tint_symbol)).y = 0u;
+ }
+ for(uint idx = local_invocation_index; (idx < 10u); idx = (idx + 1u)) {
+ uint const i = idx;
+ atomic_store_explicit(&((*(tint_symbol)).a[i]), 0u, memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomic_store_explicit(&((*(tint_symbol)).a[4]), 1u, memory_order_relaxed);
+}
+
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup S tint_symbol_1;
+ compute_main_inner(local_invocation_index, &(tint_symbol_1));
+ return;
+}
+
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.spvasm b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.spvasm
new file mode 100644
index 0000000..9d06d13
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.spvasm
@@ -0,0 +1,91 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 54
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
+ OpExecutionMode %compute_main LocalSize 1 1 1
+ OpName %local_invocation_index_1 "local_invocation_index_1"
+ OpName %S "S"
+ OpMemberName %S 0 "x"
+ OpMemberName %S 1 "a"
+ OpMemberName %S 2 "y"
+ OpName %wg "wg"
+ OpName %compute_main_inner "compute_main_inner"
+ OpName %local_invocation_index "local_invocation_index"
+ OpName %idx "idx"
+ OpName %compute_main "compute_main"
+ OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
+ OpMemberDecorate %S 0 Offset 0
+ OpMemberDecorate %S 1 Offset 4
+ OpDecorate %_arr_uint_uint_10 ArrayStride 4
+ OpMemberDecorate %S 2 Offset 44
+ %uint = OpTypeInt 32 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
+ %int = OpTypeInt 32 1
+ %uint_10 = OpConstant %uint 10
+%_arr_uint_uint_10 = OpTypeArray %uint %uint_10
+ %S = OpTypeStruct %int %_arr_uint_uint_10 %uint
+%_ptr_Workgroup_S = OpTypePointer Workgroup %S
+ %wg = OpVariable %_ptr_Workgroup_S Workgroup
+ %void = OpTypeVoid
+ %10 = OpTypeFunction %void %uint
+ %uint_0 = OpConstant %uint 0
+%_ptr_Workgroup_int = OpTypePointer Workgroup %int
+ %18 = OpConstantNull %int
+ %uint_2 = OpConstant %uint 2
+%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
+ %22 = OpConstantNull %uint
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %bool = OpTypeBool
+ %uint_1 = OpConstant %uint 1
+%_ptr_Workgroup_uint_0 = OpTypePointer Workgroup %uint
+ %uint_264 = OpConstant %uint 264
+ %int_4 = OpConstant %int 4
+ %49 = OpTypeFunction %void
+%compute_main_inner = OpFunction %void None %10
+%local_invocation_index = OpFunctionParameter %uint
+ %14 = OpLabel
+ %idx = OpVariable %_ptr_Function_uint Function %22
+ %17 = OpAccessChain %_ptr_Workgroup_int %wg %uint_0
+ OpStore %17 %18
+ %21 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_2
+ OpStore %21 %22
+ OpStore %idx %local_invocation_index
+ OpBranch %25
+ %25 = OpLabel
+ OpLoopMerge %26 %27 None
+ OpBranch %28
+ %28 = OpLabel
+ %30 = OpLoad %uint %idx
+ %31 = OpULessThan %bool %30 %uint_10
+ %29 = OpLogicalNot %bool %31
+ OpSelectionMerge %33 None
+ OpBranchConditional %29 %34 %33
+ %34 = OpLabel
+ OpBranch %26
+ %33 = OpLabel
+ %35 = OpLoad %uint %idx
+ %40 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %uint_1 %35
+ OpAtomicStore %40 %uint_2 %uint_0 %22
+ OpBranch %27
+ %27 = OpLabel
+ %41 = OpLoad %uint %idx
+ %42 = OpIAdd %uint %41 %uint_1
+ OpStore %idx %42
+ OpBranch %25
+ %26 = OpLabel
+ OpControlBarrier %uint_2 %uint_2 %uint_264
+ %48 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %uint_1 %int_4
+ OpAtomicStore %48 %uint_2 %uint_0 %uint_1
+ OpReturn
+ OpFunctionEnd
+%compute_main = OpFunction %void None %49
+ %51 = OpLabel
+ %53 = OpLoad %uint %local_invocation_index_1
+ %52 = OpFunctionCall %void %compute_main_inner %53
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.wgsl b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.wgsl
new file mode 100644
index 0000000..793d8c8
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.wgsl
@@ -0,0 +1,12 @@
+struct S {
+ x : i32,
+ a : array<atomic<u32>, 10>,
+ y : u32,
+}
+
+var<workgroup> wg : S;
+
+@compute @workgroup_size(1)
+fn compute_main() {
+ atomicStore(&(wg.a[4]), 1u);
+}
diff --git a/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.glsl b/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.glsl
new file mode 100644
index 0000000..39f13a5
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.glsl
@@ -0,0 +1,24 @@
+#version 310 es
+
+struct S {
+ int x;
+ uint a;
+ uint y;
+};
+
+shared S wg;
+void compute_main(uint local_invocation_index) {
+ {
+ wg.x = 0;
+ atomicExchange(wg.a, 0u);
+ wg.y = 0u;
+ }
+ barrier();
+ atomicExchange(wg.a, 1u);
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ compute_main(gl_LocalInvocationIndex);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.hlsl b/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.hlsl
new file mode 100644
index 0000000..fb93daa
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.hlsl
@@ -0,0 +1,29 @@
+struct S {
+ int x;
+ uint a;
+ uint y;
+};
+
+groupshared S wg;
+
+struct tint_symbol_1 {
+ uint local_invocation_index : SV_GroupIndex;
+};
+
+void compute_main_inner(uint local_invocation_index) {
+ {
+ wg.x = 0;
+ uint atomic_result = 0u;
+ InterlockedExchange(wg.a, 0u, atomic_result);
+ wg.y = 0u;
+ }
+ GroupMemoryBarrierWithGroupSync();
+ uint atomic_result_1 = 0u;
+ InterlockedExchange(wg.a, 1u, atomic_result_1);
+}
+
+[numthreads(1, 1, 1)]
+void compute_main(tint_symbol_1 tint_symbol) {
+ compute_main_inner(tint_symbol.local_invocation_index);
+ return;
+}
diff --git a/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.msl b/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.msl
new file mode 100644
index 0000000..ccec811b
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.msl
@@ -0,0 +1,25 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct S {
+ int x;
+ atomic_uint a;
+ uint y;
+};
+
+void compute_main_inner(uint local_invocation_index, threadgroup S* const tint_symbol) {
+ {
+ (*(tint_symbol)).x = 0;
+ atomic_store_explicit(&((*(tint_symbol)).a), 0u, memory_order_relaxed);
+ (*(tint_symbol)).y = 0u;
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomic_store_explicit(&((*(tint_symbol)).a), 1u, memory_order_relaxed);
+}
+
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup S tint_symbol_1;
+ compute_main_inner(local_invocation_index, &(tint_symbol_1));
+ return;
+}
+
diff --git a/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.spvasm b/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.spvasm
new file mode 100644
index 0000000..acad988
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.spvasm
@@ -0,0 +1,61 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 36
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %compute_main "compute_main" %local_invocation_index_1
+ OpExecutionMode %compute_main LocalSize 1 1 1
+ OpName %local_invocation_index_1 "local_invocation_index_1"
+ OpName %S "S"
+ OpMemberName %S 0 "x"
+ OpMemberName %S 1 "a"
+ OpMemberName %S 2 "y"
+ OpName %wg "wg"
+ OpName %compute_main_inner "compute_main_inner"
+ OpName %local_invocation_index "local_invocation_index"
+ OpName %compute_main "compute_main"
+ OpDecorate %local_invocation_index_1 BuiltIn LocalInvocationIndex
+ OpMemberDecorate %S 0 Offset 0
+ OpMemberDecorate %S 1 Offset 4
+ OpMemberDecorate %S 2 Offset 8
+ %uint = OpTypeInt 32 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+%local_invocation_index_1 = OpVariable %_ptr_Input_uint Input
+ %int = OpTypeInt 32 1
+ %S = OpTypeStruct %int %uint %uint
+%_ptr_Workgroup_S = OpTypePointer Workgroup %S
+ %wg = OpVariable %_ptr_Workgroup_S Workgroup
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void %uint
+ %uint_0 = OpConstant %uint 0
+%_ptr_Workgroup_int = OpTypePointer Workgroup %int
+ %16 = OpConstantNull %int
+ %uint_2 = OpConstant %uint 2
+ %uint_1 = OpConstant %uint 1
+%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
+ %23 = OpConstantNull %uint
+%_ptr_Workgroup_uint_0 = OpTypePointer Workgroup %uint
+ %uint_264 = OpConstant %uint 264
+ %31 = OpTypeFunction %void
+%compute_main_inner = OpFunction %void None %8
+%local_invocation_index = OpFunctionParameter %uint
+ %12 = OpLabel
+ %15 = OpAccessChain %_ptr_Workgroup_int %wg %uint_0
+ OpStore %15 %16
+ %22 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_1
+ OpAtomicStore %22 %uint_2 %uint_0 %23
+ %25 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %uint_2
+ OpStore %25 %23
+ OpControlBarrier %uint_2 %uint_2 %uint_264
+ %30 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_1
+ OpAtomicStore %30 %uint_2 %uint_0 %uint_1
+ OpReturn
+ OpFunctionEnd
+%compute_main = OpFunction %void None %31
+ %33 = OpLabel
+ %35 = OpLoad %uint %local_invocation_index_1
+ %34 = OpFunctionCall %void %compute_main_inner %35
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.wgsl b/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.wgsl
new file mode 100644
index 0000000..5076b67
--- /dev/null
+++ b/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.wgsl
@@ -0,0 +1,14 @@
+struct S {
+ x : i32,
+ a : atomic<u32>,
+ y : u32,
+}
+
+var<workgroup> wg : S;
+
+@compute @workgroup_size(1)
+fn compute_main() {
+ let p0 = &(wg);
+ let p1 = &((*(p0)).a);
+ atomicStore(p1, 1u);
+}