// Run: %dxc -T vs_6_0 -E main struct S1 { float2 a; }; struct S2 { float2 b[2]; }; struct T1 { S2 c; // Need to split to match T2.f1 & T2.f2 S2 d; // Match T2.f3 exactly }; struct T2 { S1 e; S1 f; S2 g; }; // Flattend T2: need to split all fields in T2 struct T3 { float2 h; float2 i; float2 j; float2 k; }; void main() { T1 val1[2]; // val2[0]: Construct T2.e from T1.c.b[0] // CHECK: [[b_0:%\d+]] = OpAccessChain %_ptr_Function_v2float %val1 %uint_0 %int_0 %int_0 %uint_0 // CHECK-NEXT: [[b_0_val:%\d+]] = OpLoad %v2float [[b_0]] // CHECK-NEXT: [[e_val:%\d+]] = OpCompositeConstruct %S1 [[b_0_val]] // val2[0]: Construct T2.f from T1.c.b[1] // CHECK-NEXT: [[b_1:%\d+]] = OpAccessChain %_ptr_Function_v2float %val1 %uint_0 %int_0 %int_0 %uint_1 // CHECK-NEXT: [[b_1_val:%\d+]] = OpLoad %v2float [[b_1]] // CHECK-NEXT: [[f_val:%\d+]] = OpCompositeConstruct %S1 [[b_1_val]] // val2[0]: Read T1.d as T2.g // CHECK-NEXT: [[T1_d:%\d+]] = OpAccessChain %_ptr_Function_S2 %val1 %uint_0 %int_1 // CHECK-NEXT: [[d_val:%\d+]] = OpLoad %S2 [[T1_d]] // CHECK-NEXT: [[val2_0:%\d+]] = OpCompositeConstruct %T2 [[e_val]] [[f_val]] [[d_val]] // val2[1]: Construct T2.e from T1.c.b[0] // CHECK-NEXT: [[b_0:%\d+]] = OpAccessChain %_ptr_Function_v2float %val1 %uint_1 %int_0 %int_0 %uint_0 // CHECK-NEXT: [[b_0_val:%\d+]] = OpLoad %v2float [[b_0]] // CHECK-NEXT: [[e_val:%\d+]] = OpCompositeConstruct %S1 [[b_0_val]] // val2[1]: Construct T2.f from T1.c.b[1] // CHECK-NEXT: [[b_1:%\d+]] = OpAccessChain %_ptr_Function_v2float %val1 %uint_1 %int_0 %int_0 %uint_1 // CHECK-NEXT: [[b_1_val:%\d+]] = OpLoad %v2float [[b_1]] // CHECK-NEXT: [[f_val:%\d+]] = OpCompositeConstruct %S1 [[b_1_val]] // val2[1]: Read T1.d as T2.g // CHECK-NEXT: [[T1_d:%\d+]] = OpAccessChain %_ptr_Function_S2 %val1 %uint_1 %int_1 // CHECK-NEXT: [[d_val:%\d+]] = OpLoad %S2 [[T1_d]] // CHECK-NEXT: [[val2_1:%\d+]] = OpCompositeConstruct %T2 [[e_val]] [[f_val]] [[d_val]] // CHECK-NEXT: [[val2:%\d+]] = OpCompositeConstruct %_arr_T2_uint_2 [[val2_0]] [[val2_1]] // CHECK-NEXT: OpStore %val2 [[val2]] T2 val2[2] = {val1}; // val3[0]: Construct T3.h from T1.c.b[0] // CHECK-NEXT: [[b_0:%\d+]] = OpAccessChain %_ptr_Function_v2float %val1 %int_0 %int_0 %int_0 %uint_0 // CHECK-NEXT: [[h_val:%\d+]] = OpLoad %v2float [[b_0]] // val3[0]: Construct T3.i from T1.c.b[1] // CHECK-NEXT: [[b_1:%\d+]] = OpAccessChain %_ptr_Function_v2float %val1 %int_0 %int_0 %int_0 %uint_1 // CHECK-NEXT: [[i_val:%\d+]] = OpLoad %v2float [[b_1]] // val3[0]: Construct T3.j from T1.d.b[0] // CHECK-NEXT: [[b_0:%\d+]] = OpAccessChain %_ptr_Function_v2float %val1 %int_0 %int_1 %int_0 %uint_0 // CHECK-NEXT: [[j_val:%\d+]] = OpLoad %v2float [[b_0]] // val3[0]: Construct T3.k from T1.d.b[1] // CHECK-NEXT: [[b_1:%\d+]] = OpAccessChain %_ptr_Function_v2float %val1 %int_0 %int_1 %int_0 %uint_1 // CHECK-NEXT: [[k_val:%\d+]] = OpLoad %v2float [[b_1]] // CHECK-NEXT: [[val3_0:%\d+]] = OpCompositeConstruct %T3 [[h_val]] [[i_val]] [[j_val]] [[k_val]] // val3[1] // CHECK-NEXT: [[t3_val:%\d+]] = OpLoad %T3 %t3 // val3[2]: Construct T3.h from S1.a // CHECK-NEXT: [[s1_a:%\d+]] = OpAccessChain %_ptr_Function_v2float %s1 %int_0 // CHECK-NEXT: [[h_val:%\d+]] = OpLoad %v2float [[s1_a]] // val3[2]: Construct T3.i from S2.b[0] // CHECK-NEXT: [[s2_b_0:%\d+]] = OpAccessChain %_ptr_Function_v2float %s2 %int_0 %uint_0 // CHECK-NEXT: [[i_val:%\d+]] = OpLoad %v2float [[s2_b_0]] // val3[2]: Construct T3.j from S2.b[1] // CHECK-NEXT: [[s2_b_1:%\d+]] = OpAccessChain %_ptr_Function_v2float %s2 %int_0 %uint_1 // CHECK-NEXT: [[j_val:%\d+]] = OpLoad %v2float [[s2_b_1]] // val3[2]: Construct T3.k from S1.a // CHECK-NEXT: [[s1_a:%\d+]] = OpAccessChain %_ptr_Function_v2float %s1 %int_0 // CHECK-NEXT: [[k_val:%\d+]] = OpLoad %v2float [[s1_a]] // CHECK-NEXT: [[val3_2:%\d+]] = OpCompositeConstruct %T3 [[h_val]] [[i_val]] [[j_val]] [[k_val]] // CHECK-NEXT: [[val3:%\d+]] = OpCompositeConstruct %_arr_T3_uint_3 [[val3_0]] [[t3_val]] // CHECK-NEXT: OpStore %val3 [[val3]] S1 s1; S2 s2; T3 t3; T3 val3[3] = {val1[0], t3, s1, s2, s1}; }