writer/msl: Hoist array and struct initializers

Pull the HLSL transformation out to a standalone transform that can be
used by both HLSL and MSL.

The new E2E tests do not yet pass for MSL because they produce array
assignments, which will be addressed in the next patch.

Fixed: tint:826
Change-Id: Idc27c81ad45e3d4ab96d82663927d2fc1384618e
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/52842
Auto-Submit: James Price <jrprice@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
James Price
2021-06-01 12:08:20 +00:00
committed by Tint LUCI CQ
parent 1934f59427
commit 42220ba1b2
24 changed files with 941 additions and 345 deletions

View File

@@ -303,6 +303,7 @@ tint_unittests_source_set("tint_unittests_core_src") {
"../src/transform/external_texture_transform_test.cc",
"../src/transform/first_index_offset_test.cc",
"../src/transform/inline_pointer_lets_test.cc",
"../src/transform/promote_initializers_to_const_var_test.cc",
"../src/transform/renamer_test.cc",
"../src/transform/simplify_test.cc",
"../src/transform/single_entry_point_test.cc",

View File

@@ -0,0 +1,48 @@
[[stage(compute)]]
fn main() {
let x : i32 = 42;
// Test basic usage.
let empty : array<i32, 4> = array<i32, 4>();
let nonempty : array<i32, 4> = array<i32, 4>(1, 2, 3, 4);
let nonempty_with_expr : array<i32, 4> =
array<i32, 4>(1, x, x + 1, nonempty[3]);
// Test nested arrays.
let nested_empty : array<array<array<i32, 4>, 3>, 2> =
array<array<array<i32, 4>, 3>, 2>();
let nested_nonempty : array<array<array<i32, 4>, 3>, 2> =
array<array<array<i32, 4>, 3>, 2>(
array<array<i32, 4>, 3>(
array<i32, 4>(1, 2, 3, 4),
array<i32, 4>(5, 6, 7, 8),
array<i32, 4>(9, 10, 11, 12)),
array<array<i32, 4>, 3>(
array<i32, 4>(13, 14, 15, 16),
array<i32, 4>(17, 18, 19, 20),
array<i32, 4>(21, 22, 23, 24)));
let nested_nonempty_with_expr : array<array<array<i32, 4>, 3>, 2> =
array<array<array<i32, 4>, 3>, 2>(
array<array<i32, 4>, 3>(
array<i32, 4>(1, 2, x, x + 1),
array<i32, 4>(5, 6, nonempty[2], nonempty[3] + 1),
nonempty),
nested_nonempty[1]);
// Test use of constructors as sub-expressions.
let subexpr_empty : i32 = array<i32, 4>()[1];
let subexpr_nonempty : i32 = array<i32, 4>(1, 2, 3, 4)[2];
let subexpr_nonempty_with_expr : i32 =
array<i32, 4>(1, x, x + 1, nonempty[3])[2];
let subexpr_nested_empty : array<i32, 4> = array<array<i32, 4>, 2>()[1];
let subexpr_nested_nonempty : array<i32, 4> =
array<array<i32, 4>, 2>(
array<i32, 4>(1, 2, 3, 4),
array<i32, 4>(5, 6, 7, 8)
)[1];
let subexpr_nested_nonempty_with_expr : array<i32, 4> =
array<array<i32, 4>, 2>(
array<i32, 4>(1, x, x + 1, nonempty[3]),
nested_nonempty[1][2],
)[1];
}

View File

@@ -0,0 +1,38 @@
[numthreads(1, 1, 1)]
void main() {
const int x = 42;
const int empty[4] = {0, 0, 0, 0};
const int nonempty[4] = {1, 2, 3, 4};
const int nonempty_with_expr[4] = {1, x, (x + 1), nonempty[3]};
const int nested_empty[2][3][4] = {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}};
const int tint_symbol[4] = {1, 2, 3, 4};
const int tint_symbol_1[4] = {5, 6, 7, 8};
const int tint_symbol_2[4] = {9, 10, 11, 12};
const int tint_symbol_3[3][4] = {tint_symbol, tint_symbol_1, tint_symbol_2};
const int tint_symbol_4[4] = {13, 14, 15, 16};
const int tint_symbol_5[4] = {17, 18, 19, 20};
const int tint_symbol_6[4] = {21, 22, 23, 24};
const int tint_symbol_7[3][4] = {tint_symbol_4, tint_symbol_5, tint_symbol_6};
const int nested_nonempty[2][3][4] = {tint_symbol_3, tint_symbol_7};
const int tint_symbol_8[4] = {1, 2, x, (x + 1)};
const int tint_symbol_9[4] = {5, 6, nonempty[2], (nonempty[3] + 1)};
const int tint_symbol_10[3][4] = {tint_symbol_8, tint_symbol_9, nonempty};
const int nested_nonempty_with_expr[2][3][4] = {tint_symbol_10, nested_nonempty[1]};
const int tint_symbol_11[4] = {0, 0, 0, 0};
const int subexpr_empty = tint_symbol_11[1];
const int tint_symbol_12[4] = {1, 2, 3, 4};
const int subexpr_nonempty = tint_symbol_12[2];
const int tint_symbol_13[4] = {1, x, (x + 1), nonempty[3]};
const int subexpr_nonempty_with_expr = tint_symbol_13[2];
const int tint_symbol_14[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}};
const int subexpr_nested_empty[4] = tint_symbol_14[1];
const int tint_symbol_15[4] = {1, 2, 3, 4};
const int tint_symbol_16[4] = {5, 6, 7, 8};
const int tint_symbol_17[2][4] = {tint_symbol_15, tint_symbol_16};
const int subexpr_nested_nonempty[4] = tint_symbol_17[1];
const int tint_symbol_18[4] = {1, x, (x + 1), nonempty[3]};
const int tint_symbol_19[2][4] = {tint_symbol_18, nested_nonempty[1][2]};
const int subexpr_nested_nonempty_with_expr[4] = tint_symbol_19[1];
return;
}

View File

@@ -0,0 +1 @@
SKIP: crbug.com/tint/814

View File

@@ -0,0 +1,94 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 79
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
OpName %main "main"
OpDecorate %_arr_int_uint_4 ArrayStride 4
OpDecorate %_arr__arr_int_uint_4_uint_3 ArrayStride 16
OpDecorate %_arr__arr__arr_int_uint_4_uint_3_uint_2 ArrayStride 48
OpDecorate %_arr__arr_int_uint_4_uint_2 ArrayStride 16
%void = OpTypeVoid
%1 = OpTypeFunction %void
%int = OpTypeInt 32 1
%int_42 = OpConstant %int 42
%uint = OpTypeInt 32 0
%uint_4 = OpConstant %uint 4
%_arr_int_uint_4 = OpTypeArray %int %uint_4
%10 = OpConstantNull %_arr_int_uint_4
%int_1 = OpConstant %int 1
%int_2 = OpConstant %int 2
%int_3 = OpConstant %int 3
%int_4 = OpConstant %int 4
%15 = OpConstantComposite %_arr_int_uint_4 %int_1 %int_2 %int_3 %int_4
%uint_3 = OpConstant %uint 3
%_arr__arr_int_uint_4_uint_3 = OpTypeArray %_arr_int_uint_4 %uint_3
%uint_2 = OpConstant %uint 2
%_arr__arr__arr_int_uint_4_uint_3_uint_2 = OpTypeArray %_arr__arr_int_uint_4_uint_3 %uint_2
%23 = OpConstantNull %_arr__arr__arr_int_uint_4_uint_3_uint_2
%int_5 = OpConstant %int 5
%int_6 = OpConstant %int 6
%int_7 = OpConstant %int 7
%int_8 = OpConstant %int 8
%28 = OpConstantComposite %_arr_int_uint_4 %int_5 %int_6 %int_7 %int_8
%int_9 = OpConstant %int 9
%int_10 = OpConstant %int 10
%int_11 = OpConstant %int 11
%int_12 = OpConstant %int 12
%33 = OpConstantComposite %_arr_int_uint_4 %int_9 %int_10 %int_11 %int_12
%34 = OpConstantComposite %_arr__arr_int_uint_4_uint_3 %15 %28 %33
%int_13 = OpConstant %int 13
%int_14 = OpConstant %int 14
%int_15 = OpConstant %int 15
%int_16 = OpConstant %int 16
%39 = OpConstantComposite %_arr_int_uint_4 %int_13 %int_14 %int_15 %int_16
%int_17 = OpConstant %int 17
%int_18 = OpConstant %int 18
%int_19 = OpConstant %int 19
%int_20 = OpConstant %int 20
%44 = OpConstantComposite %_arr_int_uint_4 %int_17 %int_18 %int_19 %int_20
%int_21 = OpConstant %int 21
%int_22 = OpConstant %int 22
%int_23 = OpConstant %int 23
%int_24 = OpConstant %int 24
%49 = OpConstantComposite %_arr_int_uint_4 %int_21 %int_22 %int_23 %int_24
%50 = OpConstantComposite %_arr__arr_int_uint_4_uint_3 %39 %44 %49
%51 = OpConstantComposite %_arr__arr__arr_int_uint_4_uint_3_uint_2 %34 %50
%_arr__arr_int_uint_4_uint_2 = OpTypeArray %_arr_int_uint_4 %uint_2
%68 = OpConstantNull %_arr__arr_int_uint_4_uint_2
%70 = OpConstantComposite %_arr__arr_int_uint_4_uint_2 %15 %28
%main = OpFunction %void None %1
%4 = OpLabel
%16 = OpIAdd %int %int_42 %int_1
%17 = OpCompositeExtract %int %15 3
%18 = OpCompositeConstruct %_arr_int_uint_4 %int_1 %int_42 %16 %17
%52 = OpIAdd %int %int_42 %int_1
%53 = OpCompositeConstruct %_arr_int_uint_4 %int_1 %int_2 %int_42 %52
%54 = OpCompositeExtract %int %15 2
%55 = OpCompositeExtract %int %15 3
%56 = OpIAdd %int %55 %int_1
%57 = OpCompositeConstruct %_arr_int_uint_4 %int_5 %int_6 %54 %56
%58 = OpCompositeConstruct %_arr__arr_int_uint_4_uint_3 %53 %57 %15
%59 = OpCompositeExtract %_arr__arr_int_uint_4_uint_3 %51 1
%60 = OpCompositeConstruct %_arr__arr__arr_int_uint_4_uint_3_uint_2 %58 %59
%61 = OpCompositeExtract %int %10 1
%62 = OpCompositeExtract %int %15 2
%63 = OpIAdd %int %int_42 %int_1
%64 = OpCompositeExtract %int %15 3
%65 = OpCompositeConstruct %_arr_int_uint_4 %int_1 %int_42 %63 %64
%66 = OpCompositeExtract %int %65 2
%69 = OpCompositeExtract %_arr_int_uint_4 %68 1
%71 = OpCompositeExtract %_arr_int_uint_4 %70 1
%72 = OpIAdd %int %int_42 %int_1
%73 = OpCompositeExtract %int %15 3
%74 = OpCompositeConstruct %_arr_int_uint_4 %int_1 %int_42 %72 %73
%75 = OpCompositeExtract %_arr__arr_int_uint_4_uint_3 %51 1
%76 = OpCompositeExtract %_arr_int_uint_4 %75 2
%77 = OpCompositeConstruct %_arr__arr_int_uint_4_uint_2 %74 %76
%78 = OpCompositeExtract %_arr_int_uint_4 %77 1
OpReturn
OpFunctionEnd

View File

@@ -0,0 +1,16 @@
[[stage(compute)]]
fn main() {
let x : i32 = 42;
let empty : array<i32, 4> = array<i32, 4>();
let nonempty : array<i32, 4> = array<i32, 4>(1, 2, 3, 4);
let nonempty_with_expr : array<i32, 4> = array<i32, 4>(1, x, (x + 1), nonempty[3]);
let nested_empty : array<array<array<i32, 4>, 3>, 2> = array<array<array<i32, 4>, 3>, 2>();
let nested_nonempty : array<array<array<i32, 4>, 3>, 2> = array<array<array<i32, 4>, 3>, 2>(array<array<i32, 4>, 3>(array<i32, 4>(1, 2, 3, 4), array<i32, 4>(5, 6, 7, 8), array<i32, 4>(9, 10, 11, 12)), array<array<i32, 4>, 3>(array<i32, 4>(13, 14, 15, 16), array<i32, 4>(17, 18, 19, 20), array<i32, 4>(21, 22, 23, 24)));
let nested_nonempty_with_expr : array<array<array<i32, 4>, 3>, 2> = array<array<array<i32, 4>, 3>, 2>(array<array<i32, 4>, 3>(array<i32, 4>(1, 2, x, (x + 1)), array<i32, 4>(5, 6, nonempty[2], (nonempty[3] + 1)), nonempty), nested_nonempty[1]);
let subexpr_empty : i32 = array<i32, 4>()[1];
let subexpr_nonempty : i32 = array<i32, 4>(1, 2, 3, 4)[2];
let subexpr_nonempty_with_expr : i32 = array<i32, 4>(1, x, (x + 1), nonempty[3])[2];
let subexpr_nested_empty : array<i32, 4> = array<array<i32, 4>, 2>()[1];
let subexpr_nested_nonempty : array<i32, 4> = array<array<i32, 4>, 2>(array<i32, 4>(1, 2, 3, 4), array<i32, 4>(5, 6, 7, 8))[1];
let subexpr_nested_nonempty_with_expr : array<i32, 4> = array<array<i32, 4>, 2>(array<i32, 4>(1, x, (x + 1), nonempty[3]), nested_nonempty[1][2])[1];
}

View File

@@ -81,6 +81,7 @@ void matrix_matrix_f32() {
}
fragment tint_symbol_1 tint_symbol() {
return {float4(0.0f, 0.0f, 0.0f, 0.0f)};
tint_symbol_1 const tint_symbol_2 = {float4(0.0f, 0.0f, 0.0f, 0.0f)};
return tint_symbol_2;
}

View File

@@ -32,11 +32,13 @@ vertex tint_symbol_2 vtx_main(tint_symbol_1 tint_symbol [[stage_in]], constant U
VertexOutput output = {};
output.Position = (uniforms.modelViewProjectionMatrix * input.cur_position);
output.vtxFragColor = input.color;
return {output.vtxFragColor, output.Position};
tint_symbol_2 const tint_symbol_6 = {output.vtxFragColor, output.Position};
return tint_symbol_6;
}
fragment tint_symbol_5 frag_main(tint_symbol_4 tint_symbol_3 [[stage_in]]) {
float4 const fragColor = tint_symbol_3.fragColor;
return {fragColor};
tint_symbol_5 const tint_symbol_7 = {fragColor};
return tint_symbol_7;
}

View File

@@ -11,6 +11,7 @@ void bar() {
fragment tint_symbol_1 tint_symbol() {
float2 a = float2();
bar();
return {float4(0.400000006f, 0.400000006f, 0.800000012f, 1.0f)};
tint_symbol_1 const tint_symbol_2 = {float4(0.400000006f, 0.400000006f, 0.800000012f, 1.0f)};
return tint_symbol_2;
}

View File

@@ -0,0 +1,59 @@
struct S1 {
a : i32;
b : i32;
c : i32;
d : i32;
};
struct S2 {
e : i32;
f : S1;
};
struct S3 {
g : i32;
h : S1;
i : S2;
};
struct T {
a : array<i32, 2>;
};
[[stage(compute)]]
fn main() {
let x : i32 = 42;
// Test basic usage.
let empty : S1 = S1();
let nonempty : S1 = S1(1, 2, 3, 4);
let nonempty_with_expr : S1 = S1(1, x, x + 1, nonempty.d);
// Test nested structs.
let nested_empty : S3 = S3();
let nested_nonempty : S3 = S3(1, S1(2, 3, 4, 5), S2(6, S1(7, 8, 9, 10)));
let nested_nonempty_with_expr : S3 =
S3(1, S1(2, x, x + 1, nested_nonempty.i.f.d), S2(6, nonempty));
// Test use of constructors as sub-expressions.
let subexpr_empty : i32 = S1().a;
let subexpr_nonempty : i32 = S1(1, 2, 3, 4).b;
let subexpr_nonempty_with_expr : i32 = S1(1, x, x + 1, nonempty.d).c;
let subexpr_nested_empty : S1 = S2().f;
let subexpr_nested_nonempty : S1 = S2(1, S1(2, 3, 4, 5)).f;
let subexpr_nested_nonempty_with_expr : S1 =
S2(1, S1(2, x, x + 1, nested_nonempty.i.f.d)).f;
// Test arrays of structs containing arrays.
let aosoa_empty : array<T, 2> = array<T, 2>();
let aosoa_nonempty : array<T, 2> =
array<T, 2>(
T(array<i32, 2>(1, 2)),
T(array<i32, 2>(3, 4)),
);
let aosoa_nonempty_with_expr : array<T, 2> =
array<T, 2>(
T(array<i32, 2>(1, aosoa_nonempty[0].a[0] + 1)),
aosoa_nonempty[1],
);
}

View File

@@ -0,0 +1,59 @@
struct S1 {
int a;
int b;
int c;
int d;
};
struct S2 {
int e;
S1 f;
};
struct S3 {
int g;
S1 h;
S2 i;
};
struct T {
int a[2];
};
[numthreads(1, 1, 1)]
void main() {
const int x = 42;
const S1 empty = {0, 0, 0, 0};
const S1 nonempty = {1, 2, 3, 4};
const S1 nonempty_with_expr = {1, x, (x + 1), nonempty.d};
const S3 nested_empty = {0, {0, 0, 0, 0}, {0, {0, 0, 0, 0}}};
const S1 tint_symbol = {2, 3, 4, 5};
const S1 tint_symbol_1 = {7, 8, 9, 10};
const S2 tint_symbol_2 = {6, tint_symbol_1};
const S3 nested_nonempty = {1, tint_symbol, tint_symbol_2};
const S1 tint_symbol_3 = {2, x, (x + 1), nested_nonempty.i.f.d};
const S2 tint_symbol_4 = {6, nonempty};
const S3 nested_nonempty_with_expr = {1, tint_symbol_3, tint_symbol_4};
const S1 tint_symbol_5 = {0, 0, 0, 0};
const int subexpr_empty = tint_symbol_5.a;
const S1 tint_symbol_6 = {1, 2, 3, 4};
const int subexpr_nonempty = tint_symbol_6.b;
const S1 tint_symbol_7 = {1, x, (x + 1), nonempty.d};
const int subexpr_nonempty_with_expr = tint_symbol_7.c;
const S2 tint_symbol_8 = {0, {0, 0, 0, 0}};
const S1 subexpr_nested_empty = tint_symbol_8.f;
const S1 tint_symbol_9 = {2, 3, 4, 5};
const S2 tint_symbol_10 = {1, tint_symbol_9};
const S1 subexpr_nested_nonempty = tint_symbol_10.f;
const S1 tint_symbol_11 = {2, x, (x + 1), nested_nonempty.i.f.d};
const S2 tint_symbol_12 = {1, tint_symbol_11};
const S1 subexpr_nested_nonempty_with_expr = tint_symbol_12.f;
const T aosoa_empty[2] = {{{0, 0}}, {{0, 0}}};
const int tint_symbol_13[2] = {1, 2};
const T tint_symbol_14 = {tint_symbol_13};
const int tint_symbol_15[2] = {3, 4};
const T tint_symbol_16 = {tint_symbol_15};
const T aosoa_nonempty[2] = {tint_symbol_14, tint_symbol_16};
const int tint_symbol_17[2] = {1, (aosoa_nonempty[0].a[0] + 1)};
const T tint_symbol_18 = {tint_symbol_17};
const T aosoa_nonempty_with_expr[2] = {tint_symbol_18, aosoa_nonempty[1]};
return;
}

View File

@@ -0,0 +1 @@
SKIP: crbug.com/tint/814

View File

@@ -0,0 +1,111 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 74
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
OpName %main "main"
OpName %S1 "S1"
OpMemberName %S1 0 "a"
OpMemberName %S1 1 "b"
OpMemberName %S1 2 "c"
OpMemberName %S1 3 "d"
OpName %S3 "S3"
OpMemberName %S3 0 "g"
OpMemberName %S3 1 "h"
OpMemberName %S3 2 "i"
OpName %S2 "S2"
OpMemberName %S2 0 "e"
OpMemberName %S2 1 "f"
OpName %T "T"
OpMemberName %T 0 "a"
OpMemberDecorate %S1 0 Offset 0
OpMemberDecorate %S1 1 Offset 4
OpMemberDecorate %S1 2 Offset 8
OpMemberDecorate %S1 3 Offset 12
OpMemberDecorate %S3 0 Offset 0
OpMemberDecorate %S3 1 Offset 4
OpMemberDecorate %S3 2 Offset 20
OpMemberDecorate %S2 0 Offset 0
OpMemberDecorate %S2 1 Offset 4
OpMemberDecorate %T 0 Offset 0
OpDecorate %_arr_int_uint_2 ArrayStride 4
OpDecorate %_arr_T_uint_2 ArrayStride 8
%void = OpTypeVoid
%1 = OpTypeFunction %void
%int = OpTypeInt 32 1
%int_42 = OpConstant %int 42
%S1 = OpTypeStruct %int %int %int %int
%8 = OpConstantNull %S1
%int_1 = OpConstant %int 1
%int_2 = OpConstant %int 2
%int_3 = OpConstant %int 3
%int_4 = OpConstant %int 4
%13 = OpConstantComposite %S1 %int_1 %int_2 %int_3 %int_4
%S2 = OpTypeStruct %int %S1
%S3 = OpTypeStruct %int %S1 %S2
%19 = OpConstantNull %S3
%int_5 = OpConstant %int 5
%21 = OpConstantComposite %S1 %int_2 %int_3 %int_4 %int_5
%int_6 = OpConstant %int 6
%int_7 = OpConstant %int 7
%int_8 = OpConstant %int 8
%int_9 = OpConstant %int 9
%int_10 = OpConstant %int 10
%27 = OpConstantComposite %S1 %int_7 %int_8 %int_9 %int_10
%28 = OpConstantComposite %S2 %int_6 %27
%29 = OpConstantComposite %S3 %int_1 %21 %28
%43 = OpConstantNull %S2
%45 = OpConstantComposite %S2 %int_1 %21
%uint = OpTypeInt 32 0
%uint_2 = OpConstant %uint 2
%_arr_int_uint_2 = OpTypeArray %int %uint_2
%T = OpTypeStruct %_arr_int_uint_2
%_arr_T_uint_2 = OpTypeArray %T %uint_2
%59 = OpConstantNull %_arr_T_uint_2
%60 = OpConstantComposite %_arr_int_uint_2 %int_1 %int_2
%61 = OpConstantComposite %T %60
%62 = OpConstantComposite %_arr_int_uint_2 %int_3 %int_4
%63 = OpConstantComposite %T %62
%64 = OpConstantComposite %_arr_T_uint_2 %61 %63
%int_0 = OpConstant %int 0
%main = OpFunction %void None %1
%4 = OpLabel
%14 = OpIAdd %int %int_42 %int_1
%15 = OpCompositeExtract %int %13 3
%16 = OpCompositeConstruct %S1 %int_1 %int_42 %14 %15
%30 = OpIAdd %int %int_42 %int_1
%31 = OpCompositeExtract %S2 %29 2
%32 = OpCompositeExtract %S1 %31 1
%33 = OpCompositeExtract %int %32 3
%34 = OpCompositeConstruct %S1 %int_2 %int_42 %30 %33
%35 = OpCompositeConstruct %S2 %int_6 %13
%36 = OpCompositeConstruct %S3 %int_1 %34 %35
%37 = OpCompositeExtract %int %8 0
%38 = OpCompositeExtract %int %13 1
%39 = OpIAdd %int %int_42 %int_1
%40 = OpCompositeExtract %int %13 3
%41 = OpCompositeConstruct %S1 %int_1 %int_42 %39 %40
%42 = OpCompositeExtract %int %41 2
%44 = OpCompositeExtract %S1 %43 1
%46 = OpCompositeExtract %S1 %45 1
%47 = OpIAdd %int %int_42 %int_1
%48 = OpCompositeExtract %S2 %29 2
%49 = OpCompositeExtract %S1 %48 1
%50 = OpCompositeExtract %int %49 3
%51 = OpCompositeConstruct %S1 %int_2 %int_42 %47 %50
%52 = OpCompositeConstruct %S2 %int_1 %51
%53 = OpCompositeExtract %S1 %52 1
%66 = OpCompositeExtract %T %64 0
%67 = OpCompositeExtract %_arr_int_uint_2 %66 0
%68 = OpCompositeExtract %int %67 0
%69 = OpIAdd %int %68 %int_1
%70 = OpCompositeConstruct %_arr_int_uint_2 %int_1 %69
%71 = OpCompositeConstruct %T %70
%72 = OpCompositeExtract %T %64 1
%73 = OpCompositeConstruct %_arr_T_uint_2 %71 %72
OpReturn
OpFunctionEnd

View File

@@ -0,0 +1,41 @@
struct S1 {
a : i32;
b : i32;
c : i32;
d : i32;
};
struct S2 {
e : i32;
f : S1;
};
struct S3 {
g : i32;
h : S1;
i : S2;
};
struct T {
a : array<i32, 2>;
};
[[stage(compute)]]
fn main() {
let x : i32 = 42;
let empty : S1 = S1();
let nonempty : S1 = S1(1, 2, 3, 4);
let nonempty_with_expr : S1 = S1(1, x, (x + 1), nonempty.d);
let nested_empty : S3 = S3();
let nested_nonempty : S3 = S3(1, S1(2, 3, 4, 5), S2(6, S1(7, 8, 9, 10)));
let nested_nonempty_with_expr : S3 = S3(1, S1(2, x, (x + 1), nested_nonempty.i.f.d), S2(6, nonempty));
let subexpr_empty : i32 = S1().a;
let subexpr_nonempty : i32 = S1(1, 2, 3, 4).b;
let subexpr_nonempty_with_expr : i32 = S1(1, x, (x + 1), nonempty.d).c;
let subexpr_nested_empty : S1 = S2().f;
let subexpr_nested_nonempty : S1 = S2(1, S1(2, 3, 4, 5)).f;
let subexpr_nested_nonempty_with_expr : S1 = S2(1, S1(2, x, (x + 1), nested_nonempty.i.f.d)).f;
let aosoa_empty : array<T, 2> = array<T, 2>();
let aosoa_nonempty : array<T, 2> = array<T, 2>(T(array<i32, 2>(1, 2)), T(array<i32, 2>(3, 4)));
let aosoa_nonempty_with_expr : array<T, 2> = array<T, 2>(T(array<i32, 2>(1, (aosoa_nonempty[0].a[0] + 1))), aosoa_nonempty[1]);
}