xref: /llvm-project/clang/test/CodeGen/AArch64/ABI-align-packed.c (revision 207e5ccceec8d3cc3f32723e78f2a142bc61b07d)
1*207e5cccSFangrui Song // REQUIRES: aarch64-registered-target
2*207e5cccSFangrui Song // RUN: %clang_cc1 -triple aarch64 -target-feature +neon -emit-llvm -O2 -o - %s | FileCheck %s
3*207e5cccSFangrui Song #include <stdarg.h>
4*207e5cccSFangrui Song #include <arm_neon.h>
5*207e5cccSFangrui Song 
6*207e5cccSFangrui Song // natural alignment 16, adjusted alignment 16
7*207e5cccSFangrui Song // expected alignment of copy on callee stack: 16
8*207e5cccSFangrui Song struct non_packed_struct {
9*207e5cccSFangrui Song   uint16x8_t M0; // member alignment 16
10*207e5cccSFangrui Song };
11*207e5cccSFangrui Song 
12*207e5cccSFangrui Song // natural alignment 1, adjusted alignment 1
13*207e5cccSFangrui Song // expected alignment of copy on callee stack: 8
14*207e5cccSFangrui Song struct __attribute((packed)) packed_struct {
15*207e5cccSFangrui Song   uint16x8_t M0; // member alignment 1, because the field is packed when the struct is packed
16*207e5cccSFangrui Song };
17*207e5cccSFangrui Song 
18*207e5cccSFangrui Song // natural alignment 1, adjusted alignment 1
19*207e5cccSFangrui Song // expected alignment of copy on callee stack: 8
20*207e5cccSFangrui Song struct packed_member {
21*207e5cccSFangrui Song   uint16x8_t M0 __attribute((packed)); // member alignment 1
22*207e5cccSFangrui Song };
23*207e5cccSFangrui Song 
24*207e5cccSFangrui Song // natural alignment 16, adjusted alignment 16, despite the 8-byte alignment specified by the attribute, because the natural alignment
25*207e5cccSFangrui Song // for the vector type is 16 and the attribute cannot decrease the minimum required alignment to be less.
26*207e5cccSFangrui Song // expected alignment of copy on callee stack: 16
27*207e5cccSFangrui Song struct __attribute((aligned (8))) aligned_struct_8 {
28*207e5cccSFangrui Song   uint16x8_t M0; // member alignment 16
29*207e5cccSFangrui Song };
30*207e5cccSFangrui Song 
31*207e5cccSFangrui Song // natural alignment 16, adjusted alignment 16
32*207e5cccSFangrui Song // expected alignment of copy on callee stack: 16
33*207e5cccSFangrui Song struct aligned_member_8 {
34*207e5cccSFangrui Song   uint16x8_t M0 __attribute((aligned (8))); // member alignment 16, despite the 8-byte alignment specified by the attribute,
35*207e5cccSFangrui Song   // because the natural alignment for the vector type is 16 and the attribute cannot decrease the minimum required alignment to be less.
36*207e5cccSFangrui Song };
37*207e5cccSFangrui Song 
38*207e5cccSFangrui Song // natural alignment 8, adjusted alignment 8
39*207e5cccSFangrui Song // expected alignment of copy on callee stack: 8
40*207e5cccSFangrui Song #pragma pack(8)
41*207e5cccSFangrui Song struct pragma_packed_struct_8 {
42*207e5cccSFangrui Song   uint16x8_t M0; // member alignment 8 because the struct is subject to packed(8)
43*207e5cccSFangrui Song };
44*207e5cccSFangrui Song 
45*207e5cccSFangrui Song // natural alignment 4, adjusted alignment 4
46*207e5cccSFangrui Song // expected alignment of copy on callee stack: 8
47*207e5cccSFangrui Song #pragma pack(4)
48*207e5cccSFangrui Song struct pragma_packed_struct_4 {
49*207e5cccSFangrui Song   uint16x8_t M0; // member alignment 4 because the struct is subject to packed(4)
50*207e5cccSFangrui Song };
51*207e5cccSFangrui Song 
52*207e5cccSFangrui Song double gd;
53*207e5cccSFangrui Song void init(int, ...);
54*207e5cccSFangrui Song 
55*207e5cccSFangrui Song struct non_packed_struct gs_non_packed_struct;
56*207e5cccSFangrui Song 
57*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @named_arg_non_packed_struct
58*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double noundef [[D8:%.*]], [1 x <8 x i16>] alignstack(16) [[S_NON_PACKED_STRUCT_COERCE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
59*207e5cccSFangrui Song // CHECK-NEXT:  entry:
60*207e5cccSFangrui Song // CHECK-NEXT:    [[S_NON_PACKED_STRUCT_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_NON_PACKED_STRUCT_COERCE]], 0
61*207e5cccSFangrui Song // CHECK-NEXT:    store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2:![0-9]+]]
62*207e5cccSFangrui Song // CHECK-NEXT:    store <8 x i16> [[S_NON_PACKED_STRUCT_COERCE_FCA_0_EXTRACT]], ptr @gs_non_packed_struct, align 16, !tbaa [[TBAA6:![0-9]+]]
63*207e5cccSFangrui Song // CHECK-NEXT:    ret void
64*207e5cccSFangrui Song __attribute__((noinline)) void named_arg_non_packed_struct(double d0, double d1, double d2, double d3,
65*207e5cccSFangrui Song                                  double d4, double d5, double d6, double d7,
66*207e5cccSFangrui Song                                  double d8, struct non_packed_struct s_non_packed_struct) {
67*207e5cccSFangrui Song     gd = d8;
68*207e5cccSFangrui Song     gs_non_packed_struct = s_non_packed_struct;
69*207e5cccSFangrui Song }
70*207e5cccSFangrui Song 
71*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @variadic_non_packed_struct
72*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1:[0-9]+]] {
73*207e5cccSFangrui Song // CHECK-NEXT:  entry:
74*207e5cccSFangrui Song // CHECK-NEXT:    [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
75*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6:[0-9]+]]
76*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.va_start.p0(ptr nonnull [[VL]])
77*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
78*207e5cccSFangrui Song // CHECK-NEXT:    ret void
79*207e5cccSFangrui Song void variadic_non_packed_struct(double d0, double d1, double d2, double d3,
80*207e5cccSFangrui Song                                  double d4, double d5, double d6, double d7,
81*207e5cccSFangrui Song                                  double d8, ...) {
82*207e5cccSFangrui Song   va_list vl;
83*207e5cccSFangrui Song   va_start(vl, d8);
84*207e5cccSFangrui Song   struct non_packed_struct on_callee_stack;
85*207e5cccSFangrui Song   on_callee_stack = va_arg(vl, struct non_packed_struct);
86*207e5cccSFangrui Song }
87*207e5cccSFangrui Song 
88*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @test_non_packed_struct
89*207e5cccSFangrui Song // CHECK-SAME: () local_unnamed_addr #[[ATTR4:[0-9]+]] {
90*207e5cccSFangrui Song // CHECK-NEXT:  entry:
91*207e5cccSFangrui Song // CHECK-NEXT:    [[S_NON_PACKED_STRUCT:%.*]] = alloca [[STRUCT_NON_PACKED_STRUCT:%.*]], align 16
92*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_NON_PACKED_STRUCT]]) #[[ATTR6]]
93*207e5cccSFangrui Song // CHECK-NEXT:    call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_NON_PACKED_STRUCT]]) #[[ATTR6]]
94*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_NON_PACKED_STRUCT]], align 16
95*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
96*207e5cccSFangrui Song // CHECK-NEXT:    call void @named_arg_non_packed_struct(double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, double noundef 2.000000e+00, [1 x <8 x i16>] alignstack(16) [[DOTFCA_0_INSERT]])
97*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_NON_PACKED_STRUCT]], align 16
98*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
99*207e5cccSFangrui Song // CHECK-NEXT:    call void (double, double, double, double, double, double, double, double, double, ...) @variadic_non_packed_struct(double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, [1 x <8 x i16>] alignstack(16) [[DOTFCA_0_INSERT4]])
100*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_NON_PACKED_STRUCT]]) #[[ATTR6]]
101*207e5cccSFangrui Song // CHECK-NEXT:    ret void
102*207e5cccSFangrui Song void test_non_packed_struct() {
103*207e5cccSFangrui Song     struct non_packed_struct s_non_packed_struct;
104*207e5cccSFangrui Song     init(1, &s_non_packed_struct);
105*207e5cccSFangrui Song 
106*207e5cccSFangrui Song     named_arg_non_packed_struct(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_non_packed_struct);
107*207e5cccSFangrui Song     variadic_non_packed_struct(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_non_packed_struct);
108*207e5cccSFangrui Song }
109*207e5cccSFangrui Song 
110*207e5cccSFangrui Song struct packed_struct gs_packed_struct;
111*207e5cccSFangrui Song 
112*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @named_arg_packed_struct
113*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double noundef [[D8:%.*]], [1 x <8 x i16>] alignstack(8) [[S_PACKED_STRUCT_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] {
114*207e5cccSFangrui Song // CHECK-NEXT:  entry:
115*207e5cccSFangrui Song // CHECK-NEXT:    [[S_PACKED_STRUCT_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_PACKED_STRUCT_COERCE]], 0
116*207e5cccSFangrui Song // CHECK-NEXT:    store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
117*207e5cccSFangrui Song // CHECK-NEXT:    store <8 x i16> [[S_PACKED_STRUCT_COERCE_FCA_0_EXTRACT]], ptr @gs_packed_struct, align 1, !tbaa [[TBAA6]]
118*207e5cccSFangrui Song // CHECK-NEXT:    ret void
119*207e5cccSFangrui Song __attribute__((noinline)) void named_arg_packed_struct(double d0, double d1, double d2, double d3,
120*207e5cccSFangrui Song                                  double d4, double d5, double d6, double d7,
121*207e5cccSFangrui Song                                  double d8, struct packed_struct s_packed_struct) {
122*207e5cccSFangrui Song     gd = d8;
123*207e5cccSFangrui Song     gs_packed_struct = s_packed_struct;
124*207e5cccSFangrui Song }
125*207e5cccSFangrui Song 
126*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @variadic_packed_struct
127*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] {
128*207e5cccSFangrui Song // CHECK-NEXT:  entry:
129*207e5cccSFangrui Song // CHECK-NEXT:    [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
130*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
131*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.va_start.p0(ptr nonnull [[VL]])
132*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
133*207e5cccSFangrui Song // CHECK-NEXT:    ret void
134*207e5cccSFangrui Song void variadic_packed_struct(double d0, double d1, double d2, double d3,
135*207e5cccSFangrui Song                                  double d4, double d5, double d6, double d7,
136*207e5cccSFangrui Song                                  double d8, ...) {
137*207e5cccSFangrui Song   va_list vl;
138*207e5cccSFangrui Song   va_start(vl, d8);
139*207e5cccSFangrui Song   struct packed_struct on_callee_stack;
140*207e5cccSFangrui Song   on_callee_stack = va_arg(vl, struct packed_struct);
141*207e5cccSFangrui Song }
142*207e5cccSFangrui Song 
143*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @test_packed_struct
144*207e5cccSFangrui Song // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
145*207e5cccSFangrui Song // CHECK-NEXT:  entry:
146*207e5cccSFangrui Song // CHECK-NEXT:    [[S_PACKED_STRUCT:%.*]] = alloca [[STRUCT_PACKED_STRUCT:%.*]], align 16
147*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_PACKED_STRUCT]]) #[[ATTR6]]
148*207e5cccSFangrui Song // CHECK-NEXT:    call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_PACKED_STRUCT]]) #[[ATTR6]]
149*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_PACKED_STRUCT]], align 16
150*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
151*207e5cccSFangrui Song // CHECK-NEXT:    call void @named_arg_packed_struct(double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, double noundef 2.000000e+00, [1 x <8 x i16>] alignstack(8) [[DOTFCA_0_INSERT]])
152*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_PACKED_STRUCT]], align 16
153*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
154*207e5cccSFangrui Song // CHECK-NEXT:    call void (double, double, double, double, double, double, double, double, double, ...) @variadic_packed_struct(double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, [1 x <8 x i16>] alignstack(8) [[DOTFCA_0_INSERT4]])
155*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_PACKED_STRUCT]]) #[[ATTR6]]
156*207e5cccSFangrui Song // CHECK-NEXT:    ret void
157*207e5cccSFangrui Song void test_packed_struct() {
158*207e5cccSFangrui Song     struct packed_struct s_packed_struct;
159*207e5cccSFangrui Song     init(1, &s_packed_struct);
160*207e5cccSFangrui Song 
161*207e5cccSFangrui Song     named_arg_packed_struct(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_packed_struct);
162*207e5cccSFangrui Song     variadic_packed_struct(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_packed_struct);
163*207e5cccSFangrui Song }
164*207e5cccSFangrui Song 
165*207e5cccSFangrui Song struct packed_member gs_packed_member;
166*207e5cccSFangrui Song 
167*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @named_arg_packed_member
168*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double noundef [[D8:%.*]], [1 x <8 x i16>] alignstack(8) [[S_PACKED_MEMBER_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] {
169*207e5cccSFangrui Song // CHECK-NEXT:  entry:
170*207e5cccSFangrui Song // CHECK-NEXT:    [[S_PACKED_MEMBER_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_PACKED_MEMBER_COERCE]], 0
171*207e5cccSFangrui Song // CHECK-NEXT:    store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
172*207e5cccSFangrui Song // CHECK-NEXT:    store <8 x i16> [[S_PACKED_MEMBER_COERCE_FCA_0_EXTRACT]], ptr @gs_packed_member, align 1, !tbaa [[TBAA6]]
173*207e5cccSFangrui Song // CHECK-NEXT:    ret void
174*207e5cccSFangrui Song __attribute__((noinline)) void named_arg_packed_member(double d0, double d1, double d2, double d3,
175*207e5cccSFangrui Song                                  double d4, double d5, double d6, double d7,
176*207e5cccSFangrui Song                                  double d8, struct packed_member s_packed_member) {
177*207e5cccSFangrui Song     gd = d8;
178*207e5cccSFangrui Song     gs_packed_member = s_packed_member;
179*207e5cccSFangrui Song }
180*207e5cccSFangrui Song 
181*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @variadic_packed_member
182*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] {
183*207e5cccSFangrui Song // CHECK-NEXT:  entry:
184*207e5cccSFangrui Song // CHECK-NEXT:    [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
185*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
186*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.va_start.p0(ptr nonnull [[VL]])
187*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
188*207e5cccSFangrui Song // CHECK-NEXT:    ret void
189*207e5cccSFangrui Song void variadic_packed_member(double d0, double d1, double d2, double d3,
190*207e5cccSFangrui Song                                  double d4, double d5, double d6, double d7,
191*207e5cccSFangrui Song                                  double d8, ...) {
192*207e5cccSFangrui Song   va_list vl;
193*207e5cccSFangrui Song   va_start(vl, d8);
194*207e5cccSFangrui Song   struct packed_member on_callee_stack;
195*207e5cccSFangrui Song   on_callee_stack = va_arg(vl, struct packed_member);
196*207e5cccSFangrui Song }
197*207e5cccSFangrui Song 
198*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @test_packed_member
199*207e5cccSFangrui Song // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
200*207e5cccSFangrui Song // CHECK-NEXT:  entry:
201*207e5cccSFangrui Song // CHECK-NEXT:    [[S_PACKED_MEMBER:%.*]] = alloca [[STRUCT_PACKED_MEMBER:%.*]], align 16
202*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_PACKED_MEMBER]]) #[[ATTR6]]
203*207e5cccSFangrui Song // CHECK-NEXT:    call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_PACKED_MEMBER]]) #[[ATTR6]]
204*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_PACKED_MEMBER]], align 16
205*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
206*207e5cccSFangrui Song // CHECK-NEXT:    call void @named_arg_packed_member(double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, double noundef 2.000000e+00, [1 x <8 x i16>] alignstack(8) [[DOTFCA_0_INSERT]])
207*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_PACKED_MEMBER]], align 16
208*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
209*207e5cccSFangrui Song // CHECK-NEXT:    call void (double, double, double, double, double, double, double, double, double, ...) @variadic_packed_member(double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, [1 x <8 x i16>] alignstack(8) [[DOTFCA_0_INSERT4]])
210*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_PACKED_MEMBER]]) #[[ATTR6]]
211*207e5cccSFangrui Song // CHECK-NEXT:    ret void
212*207e5cccSFangrui Song void test_packed_member() {
213*207e5cccSFangrui Song     struct packed_member s_packed_member;
214*207e5cccSFangrui Song     init(1, &s_packed_member);
215*207e5cccSFangrui Song 
216*207e5cccSFangrui Song     named_arg_packed_member(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_packed_member);
217*207e5cccSFangrui Song     variadic_packed_member(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_packed_member);
218*207e5cccSFangrui Song }
219*207e5cccSFangrui Song 
220*207e5cccSFangrui Song struct aligned_struct_8 gs_aligned_struct_8;
221*207e5cccSFangrui Song 
222*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @named_arg_aligned_struct_8
223*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double noundef [[D8:%.*]], [1 x <8 x i16>] alignstack(16) [[S_ALIGNED_STRUCT_8_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] {
224*207e5cccSFangrui Song // CHECK-NEXT:  entry:
225*207e5cccSFangrui Song // CHECK-NEXT:    [[S_ALIGNED_STRUCT_8_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_ALIGNED_STRUCT_8_COERCE]], 0
226*207e5cccSFangrui Song // CHECK-NEXT:    store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
227*207e5cccSFangrui Song // CHECK-NEXT:    store <8 x i16> [[S_ALIGNED_STRUCT_8_COERCE_FCA_0_EXTRACT]], ptr @gs_aligned_struct_8, align 16, !tbaa [[TBAA6]]
228*207e5cccSFangrui Song // CHECK-NEXT:    ret void
229*207e5cccSFangrui Song __attribute__((noinline)) void named_arg_aligned_struct_8(double d0, double d1, double d2, double d3,
230*207e5cccSFangrui Song                                  double d4, double d5, double d6, double d7,
231*207e5cccSFangrui Song                                  double d8, struct aligned_struct_8 s_aligned_struct_8) {
232*207e5cccSFangrui Song     gd = d8;
233*207e5cccSFangrui Song     gs_aligned_struct_8 = s_aligned_struct_8;
234*207e5cccSFangrui Song }
235*207e5cccSFangrui Song 
236*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @variadic_aligned_struct_8
237*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] {
238*207e5cccSFangrui Song // CHECK-NEXT:  entry:
239*207e5cccSFangrui Song // CHECK-NEXT:    [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
240*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
241*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.va_start.p0(ptr nonnull [[VL]])
242*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
243*207e5cccSFangrui Song // CHECK-NEXT:    ret void
244*207e5cccSFangrui Song void variadic_aligned_struct_8(double d0, double d1, double d2, double d3,
245*207e5cccSFangrui Song                                  double d4, double d5, double d6, double d7,
246*207e5cccSFangrui Song                                  double d8, ...) {
247*207e5cccSFangrui Song   va_list vl;
248*207e5cccSFangrui Song   va_start(vl, d8);
249*207e5cccSFangrui Song   struct aligned_struct_8 on_callee_stack;
250*207e5cccSFangrui Song   on_callee_stack = va_arg(vl, struct aligned_struct_8);
251*207e5cccSFangrui Song }
252*207e5cccSFangrui Song 
253*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @test_aligned_struct_8
254*207e5cccSFangrui Song // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
255*207e5cccSFangrui Song // CHECK-NEXT:  entry:
256*207e5cccSFangrui Song // CHECK-NEXT:    [[S_ALIGNED_STRUCT_8:%.*]] = alloca [[STRUCT_ALIGNED_STRUCT_8:%.*]], align 16
257*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_ALIGNED_STRUCT_8]]) #[[ATTR6]]
258*207e5cccSFangrui Song // CHECK-NEXT:    call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_ALIGNED_STRUCT_8]]) #[[ATTR6]]
259*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_ALIGNED_STRUCT_8]], align 16
260*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
261*207e5cccSFangrui Song // CHECK-NEXT:    call void @named_arg_aligned_struct_8(double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, double noundef 2.000000e+00, [1 x <8 x i16>] alignstack(16) [[DOTFCA_0_INSERT]])
262*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_ALIGNED_STRUCT_8]], align 16
263*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
264*207e5cccSFangrui Song // CHECK-NEXT:    call void (double, double, double, double, double, double, double, double, double, ...) @variadic_aligned_struct_8(double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, [1 x <8 x i16>] alignstack(16) [[DOTFCA_0_INSERT4]])
265*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_ALIGNED_STRUCT_8]]) #[[ATTR6]]
266*207e5cccSFangrui Song // CHECK-NEXT:    ret void
267*207e5cccSFangrui Song void test_aligned_struct_8() {
268*207e5cccSFangrui Song     struct aligned_struct_8 s_aligned_struct_8;
269*207e5cccSFangrui Song     init(1, &s_aligned_struct_8);
270*207e5cccSFangrui Song 
271*207e5cccSFangrui Song     named_arg_aligned_struct_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_aligned_struct_8);
272*207e5cccSFangrui Song     variadic_aligned_struct_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_aligned_struct_8);
273*207e5cccSFangrui Song }
274*207e5cccSFangrui Song 
275*207e5cccSFangrui Song struct aligned_member_8 gs_aligned_member_8;
276*207e5cccSFangrui Song 
277*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @named_arg_aligned_member_8
278*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double noundef [[D8:%.*]], [1 x <8 x i16>] alignstack(16) [[S_ALIGNED_MEMBER_8_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] {
279*207e5cccSFangrui Song // CHECK-NEXT:  entry:
280*207e5cccSFangrui Song // CHECK-NEXT:    [[S_ALIGNED_MEMBER_8_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_ALIGNED_MEMBER_8_COERCE]], 0
281*207e5cccSFangrui Song // CHECK-NEXT:    store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
282*207e5cccSFangrui Song // CHECK-NEXT:    store <8 x i16> [[S_ALIGNED_MEMBER_8_COERCE_FCA_0_EXTRACT]], ptr @gs_aligned_member_8, align 16, !tbaa [[TBAA6]]
283*207e5cccSFangrui Song // CHECK-NEXT:    ret void
284*207e5cccSFangrui Song __attribute__((noinline)) void named_arg_aligned_member_8(double d0, double d1, double d2, double d3,
285*207e5cccSFangrui Song                                  double d4, double d5, double d6, double d7,
286*207e5cccSFangrui Song                                  double d8, struct aligned_member_8 s_aligned_member_8) {
287*207e5cccSFangrui Song     gd = d8;
288*207e5cccSFangrui Song     gs_aligned_member_8 = s_aligned_member_8;
289*207e5cccSFangrui Song }
290*207e5cccSFangrui Song 
291*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @variadic_aligned_member_8
292*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] {
293*207e5cccSFangrui Song // CHECK-NEXT:  entry:
294*207e5cccSFangrui Song // CHECK-NEXT:    [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
295*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
296*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.va_start.p0(ptr nonnull [[VL]])
297*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
298*207e5cccSFangrui Song // CHECK-NEXT:    ret void
299*207e5cccSFangrui Song void variadic_aligned_member_8(double d0, double d1, double d2, double d3,
300*207e5cccSFangrui Song                                  double d4, double d5, double d6, double d7,
301*207e5cccSFangrui Song                                  double d8, ...) {
302*207e5cccSFangrui Song   va_list vl;
303*207e5cccSFangrui Song   va_start(vl, d8);
304*207e5cccSFangrui Song   struct aligned_member_8 on_callee_stack;
305*207e5cccSFangrui Song   on_callee_stack = va_arg(vl, struct aligned_member_8);
306*207e5cccSFangrui Song }
307*207e5cccSFangrui Song 
308*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @test_aligned_member_8
309*207e5cccSFangrui Song // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
310*207e5cccSFangrui Song // CHECK-NEXT:  entry:
311*207e5cccSFangrui Song // CHECK-NEXT:    [[S_ALIGNED_MEMBER_8:%.*]] = alloca [[STRUCT_ALIGNED_MEMBER_8:%.*]], align 16
312*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_ALIGNED_MEMBER_8]]) #[[ATTR6]]
313*207e5cccSFangrui Song // CHECK-NEXT:    call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_ALIGNED_MEMBER_8]]) #[[ATTR6]]
314*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_ALIGNED_MEMBER_8]], align 16
315*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
316*207e5cccSFangrui Song // CHECK-NEXT:    call void @named_arg_aligned_member_8(double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, double noundef 2.000000e+00, [1 x <8 x i16>] alignstack(16) [[DOTFCA_0_INSERT]])
317*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_ALIGNED_MEMBER_8]], align 16
318*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
319*207e5cccSFangrui Song // CHECK-NEXT:    call void (double, double, double, double, double, double, double, double, double, ...) @variadic_aligned_member_8(double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, [1 x <8 x i16>] alignstack(16) [[DOTFCA_0_INSERT4]])
320*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_ALIGNED_MEMBER_8]]) #[[ATTR6]]
321*207e5cccSFangrui Song // CHECK-NEXT:    ret void
322*207e5cccSFangrui Song void test_aligned_member_8() {
323*207e5cccSFangrui Song     struct aligned_member_8 s_aligned_member_8;
324*207e5cccSFangrui Song     init(1, &s_aligned_member_8);
325*207e5cccSFangrui Song 
326*207e5cccSFangrui Song     named_arg_aligned_member_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_aligned_member_8);
327*207e5cccSFangrui Song     variadic_aligned_member_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_aligned_member_8);
328*207e5cccSFangrui Song }
329*207e5cccSFangrui Song 
330*207e5cccSFangrui Song struct pragma_packed_struct_8 gs_pragma_packed_struct_8;
331*207e5cccSFangrui Song 
332*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @named_arg_pragma_packed_struct_8
333*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double noundef [[D8:%.*]], [1 x <8 x i16>] alignstack(8) [[S_PRAGMA_PACKED_STRUCT_8_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] {
334*207e5cccSFangrui Song // CHECK-NEXT:  entry:
335*207e5cccSFangrui Song // CHECK-NEXT:    [[S_PRAGMA_PACKED_STRUCT_8_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_PRAGMA_PACKED_STRUCT_8_COERCE]], 0
336*207e5cccSFangrui Song // CHECK-NEXT:    store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
337*207e5cccSFangrui Song // CHECK-NEXT:    store <8 x i16> [[S_PRAGMA_PACKED_STRUCT_8_COERCE_FCA_0_EXTRACT]], ptr @gs_pragma_packed_struct_8, align 8, !tbaa [[TBAA6]]
338*207e5cccSFangrui Song // CHECK-NEXT:    ret void
339*207e5cccSFangrui Song __attribute__((noinline)) void named_arg_pragma_packed_struct_8(double d0, double d1, double d2, double d3,
340*207e5cccSFangrui Song                                  double d4, double d5, double d6, double d7,
341*207e5cccSFangrui Song                                  double d8, struct pragma_packed_struct_8 s_pragma_packed_struct_8) {
342*207e5cccSFangrui Song     gd = d8;
343*207e5cccSFangrui Song     gs_pragma_packed_struct_8 = s_pragma_packed_struct_8;
344*207e5cccSFangrui Song }
345*207e5cccSFangrui Song 
346*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @variadic_pragma_packed_struct_8
347*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] {
348*207e5cccSFangrui Song // CHECK-NEXT:  entry:
349*207e5cccSFangrui Song // CHECK-NEXT:    [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
350*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
351*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.va_start.p0(ptr nonnull [[VL]])
352*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
353*207e5cccSFangrui Song // CHECK-NEXT:    ret void
354*207e5cccSFangrui Song void variadic_pragma_packed_struct_8(double d0, double d1, double d2, double d3,
355*207e5cccSFangrui Song                                  double d4, double d5, double d6, double d7,
356*207e5cccSFangrui Song                                  double d8, ...) {
357*207e5cccSFangrui Song   va_list vl;
358*207e5cccSFangrui Song   va_start(vl, d8);
359*207e5cccSFangrui Song   struct pragma_packed_struct_8 on_callee_stack;
360*207e5cccSFangrui Song   on_callee_stack = va_arg(vl, struct pragma_packed_struct_8);
361*207e5cccSFangrui Song }
362*207e5cccSFangrui Song 
363*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @test_pragma_packed_struct_8
364*207e5cccSFangrui Song // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
365*207e5cccSFangrui Song // CHECK-NEXT:  entry:
366*207e5cccSFangrui Song // CHECK-NEXT:    [[S_PRAGMA_PACKED_STRUCT_8:%.*]] = alloca [[STRUCT_PRAGMA_PACKED_STRUCT_8:%.*]], align 16
367*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_PRAGMA_PACKED_STRUCT_8]]) #[[ATTR6]]
368*207e5cccSFangrui Song // CHECK-NEXT:    call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_PRAGMA_PACKED_STRUCT_8]]) #[[ATTR6]]
369*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_PRAGMA_PACKED_STRUCT_8]], align 16
370*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
371*207e5cccSFangrui Song // CHECK-NEXT:    call void @named_arg_pragma_packed_struct_8(double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, double noundef 2.000000e+00, [1 x <8 x i16>] alignstack(8) [[DOTFCA_0_INSERT]])
372*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_PRAGMA_PACKED_STRUCT_8]], align 16
373*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
374*207e5cccSFangrui Song // CHECK-NEXT:    call void (double, double, double, double, double, double, double, double, double, ...) @variadic_pragma_packed_struct_8(double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, [1 x <8 x i16>] alignstack(8) [[DOTFCA_0_INSERT4]])
375*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_PRAGMA_PACKED_STRUCT_8]]) #[[ATTR6]]
376*207e5cccSFangrui Song // CHECK-NEXT:    ret void
377*207e5cccSFangrui Song void test_pragma_packed_struct_8() {
378*207e5cccSFangrui Song     struct pragma_packed_struct_8 s_pragma_packed_struct_8;
379*207e5cccSFangrui Song     init(1, &s_pragma_packed_struct_8);
380*207e5cccSFangrui Song 
381*207e5cccSFangrui Song     named_arg_pragma_packed_struct_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_pragma_packed_struct_8);
382*207e5cccSFangrui Song     variadic_pragma_packed_struct_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_pragma_packed_struct_8);
383*207e5cccSFangrui Song }
384*207e5cccSFangrui Song 
385*207e5cccSFangrui Song struct pragma_packed_struct_4 gs_pragma_packed_struct_4;
386*207e5cccSFangrui Song 
387*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @named_arg_pragma_packed_struct_4
388*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double noundef [[D8:%.*]], [1 x <8 x i16>] alignstack(8) [[S_PRAGMA_PACKED_STRUCT_4_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] {
389*207e5cccSFangrui Song // CHECK-NEXT:  entry:
390*207e5cccSFangrui Song // CHECK-NEXT:    [[S_PRAGMA_PACKED_STRUCT_4_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_PRAGMA_PACKED_STRUCT_4_COERCE]], 0
391*207e5cccSFangrui Song // CHECK-NEXT:    store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
392*207e5cccSFangrui Song // CHECK-NEXT:    store <8 x i16> [[S_PRAGMA_PACKED_STRUCT_4_COERCE_FCA_0_EXTRACT]], ptr @gs_pragma_packed_struct_4, align 4, !tbaa [[TBAA6]]
393*207e5cccSFangrui Song // CHECK-NEXT:    ret void
394*207e5cccSFangrui Song __attribute__((noinline)) void named_arg_pragma_packed_struct_4(double d0, double d1, double d2, double d3,
395*207e5cccSFangrui Song                                  double d4, double d5, double d6, double d7,
396*207e5cccSFangrui Song                                  double d8, struct pragma_packed_struct_4 s_pragma_packed_struct_4) {
397*207e5cccSFangrui Song     gd = d8;
398*207e5cccSFangrui Song     gs_pragma_packed_struct_4 = s_pragma_packed_struct_4;
399*207e5cccSFangrui Song }
400*207e5cccSFangrui Song 
401*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @variadic_pragma_packed_struct_4
402*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] {
403*207e5cccSFangrui Song // CHECK-NEXT:  entry:
404*207e5cccSFangrui Song // CHECK-NEXT:    [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
405*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
406*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.va_start.p0(ptr nonnull [[VL]])
407*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
408*207e5cccSFangrui Song // CHECK-NEXT:    ret void
409*207e5cccSFangrui Song void variadic_pragma_packed_struct_4(double d0, double d1, double d2, double d3,
410*207e5cccSFangrui Song                                  double d4, double d5, double d6, double d7,
411*207e5cccSFangrui Song                                  double d8, ...) {
412*207e5cccSFangrui Song   va_list vl;
413*207e5cccSFangrui Song   va_start(vl, d8);
414*207e5cccSFangrui Song   struct pragma_packed_struct_4 on_callee_stack;
415*207e5cccSFangrui Song   on_callee_stack = va_arg(vl, struct pragma_packed_struct_4);
416*207e5cccSFangrui Song }
417*207e5cccSFangrui Song 
418*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @test_pragma_packed_struct_4
419*207e5cccSFangrui Song // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
420*207e5cccSFangrui Song // CHECK-NEXT:  entry:
421*207e5cccSFangrui Song // CHECK-NEXT:    [[S_PRAGMA_PACKED_STRUCT_4:%.*]] = alloca [[STRUCT_PRAGMA_PACKED_STRUCT_4:%.*]], align 16
422*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_PRAGMA_PACKED_STRUCT_4]]) #[[ATTR6]]
423*207e5cccSFangrui Song // CHECK-NEXT:    call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_PRAGMA_PACKED_STRUCT_4]]) #[[ATTR6]]
424*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_PRAGMA_PACKED_STRUCT_4]], align 16
425*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
426*207e5cccSFangrui Song // CHECK-NEXT:    call void @named_arg_pragma_packed_struct_4(double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, double noundef 2.000000e+00, [1 x <8 x i16>] alignstack(8) [[DOTFCA_0_INSERT]])
427*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_PRAGMA_PACKED_STRUCT_4]], align 16
428*207e5cccSFangrui Song // CHECK-NEXT:    [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
429*207e5cccSFangrui Song // CHECK-NEXT:    call void (double, double, double, double, double, double, double, double, double, ...) @variadic_pragma_packed_struct_4(double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, double poison, [1 x <8 x i16>] alignstack(8) [[DOTFCA_0_INSERT4]])
430*207e5cccSFangrui Song // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_PRAGMA_PACKED_STRUCT_4]]) #[[ATTR6]]
431*207e5cccSFangrui Song // CHECK-NEXT:    ret void
432*207e5cccSFangrui Song void test_pragma_packed_struct_4() {
433*207e5cccSFangrui Song     struct pragma_packed_struct_4 s_pragma_packed_struct_4;
434*207e5cccSFangrui Song     init(1, &s_pragma_packed_struct_4);
435*207e5cccSFangrui Song 
436*207e5cccSFangrui Song     named_arg_pragma_packed_struct_4(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_pragma_packed_struct_4);
437*207e5cccSFangrui Song     variadic_pragma_packed_struct_4(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_pragma_packed_struct_4);
438*207e5cccSFangrui Song }
439*207e5cccSFangrui Song //.
440*207e5cccSFangrui Song // CHECK: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0}
441*207e5cccSFangrui Song // CHECK: [[META3]] = !{!"double", [[META4:![0-9]+]], i64 0}
442*207e5cccSFangrui Song // CHECK: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
443*207e5cccSFangrui Song // CHECK: [[META5]] = !{!"Simple C/C++ TBAA"}
444*207e5cccSFangrui Song // CHECK: [[TBAA6]] = !{[[META4]], [[META4]], i64 0}
445*207e5cccSFangrui Song //.
446