1 // REQUIRES: aarch64-registered-target
2 // RUN: %clang_cc1 -triple aarch64 -target-feature +neon -emit-llvm -O2 -o - %s | FileCheck %s
6 // natural alignment 16, adjusted alignment 16
7 // expected alignment of copy on callee stack: 16
8 struct non_packed_struct
{
9 uint16x8_t M0
; // member alignment 16
12 // natural alignment 1, adjusted alignment 1
13 // expected alignment of copy on callee stack: 8
14 struct __attribute((packed
)) packed_struct
{
15 uint16x8_t M0
; // member alignment 1, because the field is packed when the struct is packed
18 // natural alignment 1, adjusted alignment 1
19 // expected alignment of copy on callee stack: 8
20 struct packed_member
{
21 uint16x8_t M0
__attribute((packed
)); // member alignment 1
24 // natural alignment 16, adjusted alignment 16, despite the 8-byte alignment specified by the attribute, because the natural alignment
25 // for the vector type is 16 and the attribute cannot decrease the minimum required alignment to be less.
26 // expected alignment of copy on callee stack: 16
27 struct __attribute((aligned (8))) aligned_struct_8
{
28 uint16x8_t M0
; // member alignment 16
31 // natural alignment 16, adjusted alignment 16
32 // expected alignment of copy on callee stack: 16
33 struct aligned_member_8
{
34 uint16x8_t M0
__attribute((aligned (8))); // member alignment 16, despite the 8-byte alignment specified by the attribute,
35 // because the natural alignment for the vector type is 16 and the attribute cannot decrease the minimum required alignment to be less.
38 // natural alignment 8, adjusted alignment 8
39 // expected alignment of copy on callee stack: 8
41 struct pragma_packed_struct_8
{
42 uint16x8_t M0
; // member alignment 8 because the struct is subject to packed(8)
45 // natural alignment 4, adjusted alignment 4
46 // expected alignment of copy on callee stack: 8
48 struct pragma_packed_struct_4
{
49 uint16x8_t M0
; // member alignment 4 because the struct is subject to packed(4)
55 struct non_packed_struct gs_non_packed_struct
;
57 // CHECK-LABEL: define dso_local void @named_arg_non_packed_struct
58 // 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]+]] {
60 // CHECK-NEXT: [[S_NON_PACKED_STRUCT_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_NON_PACKED_STRUCT_COERCE]], 0
61 // CHECK-NEXT: store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2:![0-9]+]]
62 // 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 // CHECK-NEXT: ret void
64 __attribute__((noinline
)) void named_arg_non_packed_struct(double d0
, double d1
, double d2
, double d3
,
65 double d4
, double d5
, double d6
, double d7
,
66 double d8
, struct non_packed_struct s_non_packed_struct
) {
68 gs_non_packed_struct
= s_non_packed_struct
;
71 // CHECK-LABEL: define dso_local void @variadic_non_packed_struct
72 // 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]+]] {
74 // CHECK-NEXT: [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
75 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6:[0-9]+]]
76 // CHECK-NEXT: call void @llvm.va_start.p0(ptr nonnull [[VL]])
77 // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
78 // CHECK-NEXT: ret void
79 void variadic_non_packed_struct(double d0
, double d1
, double d2
, double d3
,
80 double d4
, double d5
, double d6
, double d7
,
84 struct non_packed_struct on_callee_stack
;
85 on_callee_stack
= va_arg(vl
, struct non_packed_struct
);
88 // CHECK-LABEL: define dso_local void @test_non_packed_struct
89 // CHECK-SAME: () local_unnamed_addr #[[ATTR4:[0-9]+]] {
91 // CHECK-NEXT: [[S_NON_PACKED_STRUCT:%.*]] = alloca [[STRUCT_NON_PACKED_STRUCT:%.*]], align 16
92 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_NON_PACKED_STRUCT]]) #[[ATTR6]]
93 // CHECK-NEXT: call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_NON_PACKED_STRUCT]]) #[[ATTR6]]
94 // CHECK-NEXT: [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_NON_PACKED_STRUCT]], align 16
95 // CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
96 // 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 // CHECK-NEXT: [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_NON_PACKED_STRUCT]], align 16
98 // CHECK-NEXT: [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
99 // 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 // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_NON_PACKED_STRUCT]]) #[[ATTR6]]
101 // CHECK-NEXT: ret void
102 void test_non_packed_struct() {
103 struct non_packed_struct s_non_packed_struct
;
104 init(1, &s_non_packed_struct
);
106 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 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
);
110 struct packed_struct gs_packed_struct
;
112 // CHECK-LABEL: define dso_local void @named_arg_packed_struct
113 // 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 // CHECK-NEXT: entry:
115 // CHECK-NEXT: [[S_PACKED_STRUCT_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_PACKED_STRUCT_COERCE]], 0
116 // CHECK-NEXT: store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
117 // CHECK-NEXT: store <8 x i16> [[S_PACKED_STRUCT_COERCE_FCA_0_EXTRACT]], ptr @gs_packed_struct, align 1, !tbaa [[TBAA6]]
118 // CHECK-NEXT: ret void
119 __attribute__((noinline
)) void named_arg_packed_struct(double d0
, double d1
, double d2
, double d3
,
120 double d4
, double d5
, double d6
, double d7
,
121 double d8
, struct packed_struct s_packed_struct
) {
123 gs_packed_struct
= s_packed_struct
;
126 // CHECK-LABEL: define dso_local void @variadic_packed_struct
127 // 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 // CHECK-NEXT: entry:
129 // CHECK-NEXT: [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
130 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
131 // CHECK-NEXT: call void @llvm.va_start.p0(ptr nonnull [[VL]])
132 // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
133 // CHECK-NEXT: ret void
134 void variadic_packed_struct(double d0
, double d1
, double d2
, double d3
,
135 double d4
, double d5
, double d6
, double d7
,
139 struct packed_struct on_callee_stack
;
140 on_callee_stack
= va_arg(vl
, struct packed_struct
);
143 // CHECK-LABEL: define dso_local void @test_packed_struct
144 // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
145 // CHECK-NEXT: entry:
146 // CHECK-NEXT: [[S_PACKED_STRUCT:%.*]] = alloca [[STRUCT_PACKED_STRUCT:%.*]], align 16
147 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_PACKED_STRUCT]]) #[[ATTR6]]
148 // CHECK-NEXT: call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_PACKED_STRUCT]]) #[[ATTR6]]
149 // CHECK-NEXT: [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_PACKED_STRUCT]], align 16
150 // CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
151 // 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 // CHECK-NEXT: [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_PACKED_STRUCT]], align 16
153 // CHECK-NEXT: [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
154 // 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 // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_PACKED_STRUCT]]) #[[ATTR6]]
156 // CHECK-NEXT: ret void
157 void test_packed_struct() {
158 struct packed_struct s_packed_struct
;
159 init(1, &s_packed_struct
);
161 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 variadic_packed_struct(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_packed_struct
);
165 struct packed_member gs_packed_member
;
167 // CHECK-LABEL: define dso_local void @named_arg_packed_member
168 // 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 // CHECK-NEXT: entry:
170 // CHECK-NEXT: [[S_PACKED_MEMBER_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_PACKED_MEMBER_COERCE]], 0
171 // CHECK-NEXT: store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
172 // CHECK-NEXT: store <8 x i16> [[S_PACKED_MEMBER_COERCE_FCA_0_EXTRACT]], ptr @gs_packed_member, align 1, !tbaa [[TBAA6]]
173 // CHECK-NEXT: ret void
174 __attribute__((noinline
)) void named_arg_packed_member(double d0
, double d1
, double d2
, double d3
,
175 double d4
, double d5
, double d6
, double d7
,
176 double d8
, struct packed_member s_packed_member
) {
178 gs_packed_member
= s_packed_member
;
181 // CHECK-LABEL: define dso_local void @variadic_packed_member
182 // 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 // CHECK-NEXT: entry:
184 // CHECK-NEXT: [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
185 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
186 // CHECK-NEXT: call void @llvm.va_start.p0(ptr nonnull [[VL]])
187 // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
188 // CHECK-NEXT: ret void
189 void variadic_packed_member(double d0
, double d1
, double d2
, double d3
,
190 double d4
, double d5
, double d6
, double d7
,
194 struct packed_member on_callee_stack
;
195 on_callee_stack
= va_arg(vl
, struct packed_member
);
198 // CHECK-LABEL: define dso_local void @test_packed_member
199 // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
200 // CHECK-NEXT: entry:
201 // CHECK-NEXT: [[S_PACKED_MEMBER:%.*]] = alloca [[STRUCT_PACKED_MEMBER:%.*]], align 16
202 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_PACKED_MEMBER]]) #[[ATTR6]]
203 // CHECK-NEXT: call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_PACKED_MEMBER]]) #[[ATTR6]]
204 // CHECK-NEXT: [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_PACKED_MEMBER]], align 16
205 // CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
206 // 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 // CHECK-NEXT: [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_PACKED_MEMBER]], align 16
208 // CHECK-NEXT: [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
209 // 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 // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_PACKED_MEMBER]]) #[[ATTR6]]
211 // CHECK-NEXT: ret void
212 void test_packed_member() {
213 struct packed_member s_packed_member
;
214 init(1, &s_packed_member
);
216 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 variadic_packed_member(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_packed_member
);
220 struct aligned_struct_8 gs_aligned_struct_8
;
222 // CHECK-LABEL: define dso_local void @named_arg_aligned_struct_8
223 // 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 // CHECK-NEXT: entry:
225 // CHECK-NEXT: [[S_ALIGNED_STRUCT_8_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_ALIGNED_STRUCT_8_COERCE]], 0
226 // CHECK-NEXT: store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
227 // CHECK-NEXT: store <8 x i16> [[S_ALIGNED_STRUCT_8_COERCE_FCA_0_EXTRACT]], ptr @gs_aligned_struct_8, align 16, !tbaa [[TBAA6]]
228 // CHECK-NEXT: ret void
229 __attribute__((noinline
)) void named_arg_aligned_struct_8(double d0
, double d1
, double d2
, double d3
,
230 double d4
, double d5
, double d6
, double d7
,
231 double d8
, struct aligned_struct_8 s_aligned_struct_8
) {
233 gs_aligned_struct_8
= s_aligned_struct_8
;
236 // CHECK-LABEL: define dso_local void @variadic_aligned_struct_8
237 // 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 // CHECK-NEXT: entry:
239 // CHECK-NEXT: [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
240 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
241 // CHECK-NEXT: call void @llvm.va_start.p0(ptr nonnull [[VL]])
242 // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
243 // CHECK-NEXT: ret void
244 void variadic_aligned_struct_8(double d0
, double d1
, double d2
, double d3
,
245 double d4
, double d5
, double d6
, double d7
,
249 struct aligned_struct_8 on_callee_stack
;
250 on_callee_stack
= va_arg(vl
, struct aligned_struct_8
);
253 // CHECK-LABEL: define dso_local void @test_aligned_struct_8
254 // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
255 // CHECK-NEXT: entry:
256 // CHECK-NEXT: [[S_ALIGNED_STRUCT_8:%.*]] = alloca [[STRUCT_ALIGNED_STRUCT_8:%.*]], align 16
257 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_ALIGNED_STRUCT_8]]) #[[ATTR6]]
258 // CHECK-NEXT: call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_ALIGNED_STRUCT_8]]) #[[ATTR6]]
259 // CHECK-NEXT: [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_ALIGNED_STRUCT_8]], align 16
260 // CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
261 // 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 // CHECK-NEXT: [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_ALIGNED_STRUCT_8]], align 16
263 // CHECK-NEXT: [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
264 // 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 // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_ALIGNED_STRUCT_8]]) #[[ATTR6]]
266 // CHECK-NEXT: ret void
267 void test_aligned_struct_8() {
268 struct aligned_struct_8 s_aligned_struct_8
;
269 init(1, &s_aligned_struct_8
);
271 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 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
);
275 struct aligned_member_8 gs_aligned_member_8
;
277 // CHECK-LABEL: define dso_local void @named_arg_aligned_member_8
278 // 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 // CHECK-NEXT: entry:
280 // CHECK-NEXT: [[S_ALIGNED_MEMBER_8_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_ALIGNED_MEMBER_8_COERCE]], 0
281 // CHECK-NEXT: store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
282 // CHECK-NEXT: store <8 x i16> [[S_ALIGNED_MEMBER_8_COERCE_FCA_0_EXTRACT]], ptr @gs_aligned_member_8, align 16, !tbaa [[TBAA6]]
283 // CHECK-NEXT: ret void
284 __attribute__((noinline
)) void named_arg_aligned_member_8(double d0
, double d1
, double d2
, double d3
,
285 double d4
, double d5
, double d6
, double d7
,
286 double d8
, struct aligned_member_8 s_aligned_member_8
) {
288 gs_aligned_member_8
= s_aligned_member_8
;
291 // CHECK-LABEL: define dso_local void @variadic_aligned_member_8
292 // 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 // CHECK-NEXT: entry:
294 // CHECK-NEXT: [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
295 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
296 // CHECK-NEXT: call void @llvm.va_start.p0(ptr nonnull [[VL]])
297 // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
298 // CHECK-NEXT: ret void
299 void variadic_aligned_member_8(double d0
, double d1
, double d2
, double d3
,
300 double d4
, double d5
, double d6
, double d7
,
304 struct aligned_member_8 on_callee_stack
;
305 on_callee_stack
= va_arg(vl
, struct aligned_member_8
);
308 // CHECK-LABEL: define dso_local void @test_aligned_member_8
309 // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
310 // CHECK-NEXT: entry:
311 // CHECK-NEXT: [[S_ALIGNED_MEMBER_8:%.*]] = alloca [[STRUCT_ALIGNED_MEMBER_8:%.*]], align 16
312 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_ALIGNED_MEMBER_8]]) #[[ATTR6]]
313 // CHECK-NEXT: call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_ALIGNED_MEMBER_8]]) #[[ATTR6]]
314 // CHECK-NEXT: [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_ALIGNED_MEMBER_8]], align 16
315 // CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
316 // 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 // CHECK-NEXT: [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_ALIGNED_MEMBER_8]], align 16
318 // CHECK-NEXT: [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
319 // 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 // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_ALIGNED_MEMBER_8]]) #[[ATTR6]]
321 // CHECK-NEXT: ret void
322 void test_aligned_member_8() {
323 struct aligned_member_8 s_aligned_member_8
;
324 init(1, &s_aligned_member_8
);
326 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 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
);
330 struct pragma_packed_struct_8 gs_pragma_packed_struct_8
;
332 // CHECK-LABEL: define dso_local void @named_arg_pragma_packed_struct_8
333 // 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 // CHECK-NEXT: entry:
335 // 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 // CHECK-NEXT: store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
337 // 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 // CHECK-NEXT: ret void
339 __attribute__((noinline
)) void named_arg_pragma_packed_struct_8(double d0
, double d1
, double d2
, double d3
,
340 double d4
, double d5
, double d6
, double d7
,
341 double d8
, struct pragma_packed_struct_8 s_pragma_packed_struct_8
) {
343 gs_pragma_packed_struct_8
= s_pragma_packed_struct_8
;
346 // CHECK-LABEL: define dso_local void @variadic_pragma_packed_struct_8
347 // 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 // CHECK-NEXT: entry:
349 // CHECK-NEXT: [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
350 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
351 // CHECK-NEXT: call void @llvm.va_start.p0(ptr nonnull [[VL]])
352 // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
353 // CHECK-NEXT: ret void
354 void variadic_pragma_packed_struct_8(double d0
, double d1
, double d2
, double d3
,
355 double d4
, double d5
, double d6
, double d7
,
359 struct pragma_packed_struct_8 on_callee_stack
;
360 on_callee_stack
= va_arg(vl
, struct pragma_packed_struct_8
);
363 // CHECK-LABEL: define dso_local void @test_pragma_packed_struct_8
364 // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
365 // CHECK-NEXT: entry:
366 // CHECK-NEXT: [[S_PRAGMA_PACKED_STRUCT_8:%.*]] = alloca [[STRUCT_PRAGMA_PACKED_STRUCT_8:%.*]], align 16
367 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_PRAGMA_PACKED_STRUCT_8]]) #[[ATTR6]]
368 // CHECK-NEXT: call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_PRAGMA_PACKED_STRUCT_8]]) #[[ATTR6]]
369 // CHECK-NEXT: [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_PRAGMA_PACKED_STRUCT_8]], align 16
370 // CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
371 // 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 // CHECK-NEXT: [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_PRAGMA_PACKED_STRUCT_8]], align 16
373 // CHECK-NEXT: [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
374 // 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 // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_PRAGMA_PACKED_STRUCT_8]]) #[[ATTR6]]
376 // CHECK-NEXT: ret void
377 void test_pragma_packed_struct_8() {
378 struct pragma_packed_struct_8 s_pragma_packed_struct_8
;
379 init(1, &s_pragma_packed_struct_8
);
381 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 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
);
385 struct pragma_packed_struct_4 gs_pragma_packed_struct_4
;
387 // CHECK-LABEL: define dso_local void @named_arg_pragma_packed_struct_4
388 // 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 // CHECK-NEXT: entry:
390 // 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 // CHECK-NEXT: store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
392 // 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 // CHECK-NEXT: ret void
394 __attribute__((noinline
)) void named_arg_pragma_packed_struct_4(double d0
, double d1
, double d2
, double d3
,
395 double d4
, double d5
, double d6
, double d7
,
396 double d8
, struct pragma_packed_struct_4 s_pragma_packed_struct_4
) {
398 gs_pragma_packed_struct_4
= s_pragma_packed_struct_4
;
401 // CHECK-LABEL: define dso_local void @variadic_pragma_packed_struct_4
402 // 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 // CHECK-NEXT: entry:
404 // CHECK-NEXT: [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
405 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
406 // CHECK-NEXT: call void @llvm.va_start.p0(ptr nonnull [[VL]])
407 // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]]
408 // CHECK-NEXT: ret void
409 void variadic_pragma_packed_struct_4(double d0
, double d1
, double d2
, double d3
,
410 double d4
, double d5
, double d6
, double d7
,
414 struct pragma_packed_struct_4 on_callee_stack
;
415 on_callee_stack
= va_arg(vl
, struct pragma_packed_struct_4
);
418 // CHECK-LABEL: define dso_local void @test_pragma_packed_struct_4
419 // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
420 // CHECK-NEXT: entry:
421 // CHECK-NEXT: [[S_PRAGMA_PACKED_STRUCT_4:%.*]] = alloca [[STRUCT_PRAGMA_PACKED_STRUCT_4:%.*]], align 16
422 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_PRAGMA_PACKED_STRUCT_4]]) #[[ATTR6]]
423 // CHECK-NEXT: call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_PRAGMA_PACKED_STRUCT_4]]) #[[ATTR6]]
424 // CHECK-NEXT: [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_PRAGMA_PACKED_STRUCT_4]], align 16
425 // CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
426 // 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 // CHECK-NEXT: [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_PRAGMA_PACKED_STRUCT_4]], align 16
428 // CHECK-NEXT: [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
429 // 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 // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_PRAGMA_PACKED_STRUCT_4]]) #[[ATTR6]]
431 // CHECK-NEXT: ret void
432 void test_pragma_packed_struct_4() {
433 struct pragma_packed_struct_4 s_pragma_packed_struct_4
;
434 init(1, &s_pragma_packed_struct_4
);
436 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 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
);
440 // CHECK: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0}
441 // CHECK: [[META3]] = !{!"double", [[META4:![0-9]+]], i64 0}
442 // CHECK: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
443 // CHECK: [[META5]] = !{!"Simple C/C++ TBAA"}
444 // CHECK: [[TBAA6]] = !{[[META4]], [[META4]], i64 0}