comparison clang/test/CodeGen/aarch64-varargs.c @ 207:2e18cbf3894f

LLVM12
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 08 Jun 2021 06:07:14 +0900
parents 0572611fdcc8
children 5f17cb93ff66
comparison
equal deleted inserted replaced
173:0572611fdcc8 207:2e18cbf3894f
7 // least prevent unintentional regressions caused by refactoring. 7 // least prevent unintentional regressions caused by refactoring.
8 8
9 va_list the_list; 9 va_list the_list;
10 10
11 int simple_int(void) { 11 int simple_int(void) {
12 // CHECK-LABEL: define i32 @simple_int 12 // CHECK-LABEL: define{{.*}} i32 @simple_int
13 return va_arg(the_list, int); 13 return va_arg(the_list, int);
14 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 14 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
15 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 15 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
16 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 16 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
17 17
43 // CHECK: [[RESULT:%[a-z_0-9]+]] = load i32, i32* [[ADDR]] 43 // CHECK: [[RESULT:%[a-z_0-9]+]] = load i32, i32* [[ADDR]]
44 // CHECK: ret i32 [[RESULT]] 44 // CHECK: ret i32 [[RESULT]]
45 } 45 }
46 46
47 __int128 aligned_int(void) { 47 __int128 aligned_int(void) {
48 // CHECK-LABEL: define i128 @aligned_int 48 // CHECK-LABEL: define{{.*}} i128 @aligned_int
49 return va_arg(the_list, __int128); 49 return va_arg(the_list, __int128);
50 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 50 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
51 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 51 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
52 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 52 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
53 53
85 struct bigstruct { 85 struct bigstruct {
86 int a[10]; 86 int a[10];
87 }; 87 };
88 88
89 struct bigstruct simple_indirect(void) { 89 struct bigstruct simple_indirect(void) {
90 // CHECK-LABEL: define void @simple_indirect 90 // CHECK-LABEL: define{{.*}} void @simple_indirect
91 return va_arg(the_list, struct bigstruct); 91 return va_arg(the_list, struct bigstruct);
92 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 92 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
93 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 93 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
94 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 94 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
95 95
123 float a; 123 float a;
124 long double b; 124 long double b;
125 }; 125 };
126 126
127 struct aligned_bigstruct simple_aligned_indirect(void) { 127 struct aligned_bigstruct simple_aligned_indirect(void) {
128 // CHECK-LABEL: define void @simple_aligned_indirect 128 // CHECK-LABEL: define{{.*}} void @simple_aligned_indirect
129 return va_arg(the_list, struct aligned_bigstruct); 129 return va_arg(the_list, struct aligned_bigstruct);
130 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 130 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
131 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 131 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
132 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 132 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
133 133
154 // CHECK: [[ADDR:%[a-z._0-9]+]] = phi %struct.aligned_bigstruct** [ [[FROMREG_ADDR]], %[[VAARG_IN_REG]] ], [ [[FROMSTACK_ADDR]], %[[VAARG_ON_STACK]] ] 154 // CHECK: [[ADDR:%[a-z._0-9]+]] = phi %struct.aligned_bigstruct** [ [[FROMREG_ADDR]], %[[VAARG_IN_REG]] ], [ [[FROMSTACK_ADDR]], %[[VAARG_ON_STACK]] ]
155 // CHECK: load %struct.aligned_bigstruct*, %struct.aligned_bigstruct** [[ADDR]] 155 // CHECK: load %struct.aligned_bigstruct*, %struct.aligned_bigstruct** [[ADDR]]
156 } 156 }
157 157
158 double simple_double(void) { 158 double simple_double(void) {
159 // CHECK-LABEL: define double @simple_double 159 // CHECK-LABEL: define{{.*}} double @simple_double
160 return va_arg(the_list, double); 160 return va_arg(the_list, double);
161 // CHECK: [[VR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 4) 161 // CHECK: [[VR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 4)
162 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[VR_OFFS]], 0 162 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[VR_OFFS]], 0
163 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG]] 163 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG]]
164 164
192 struct hfa { 192 struct hfa {
193 float a, b; 193 float a, b;
194 }; 194 };
195 195
196 struct hfa simple_hfa(void) { 196 struct hfa simple_hfa(void) {
197 // CHECK-LABEL: define %struct.hfa @simple_hfa 197 // CHECK-LABEL: define{{.*}} %struct.hfa @simple_hfa
198 return va_arg(the_list, struct hfa); 198 return va_arg(the_list, struct hfa);
199 // CHECK: [[VR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 4) 199 // CHECK: [[VR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 4)
200 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[VR_OFFS]], 0 200 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[VR_OFFS]], 0
201 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 201 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
202 202
239 // passing, so the code generated for va_arg should be the same as for 239 // passing, so the code generated for va_arg should be the same as for
240 // non-aligned fundamental types. 240 // non-aligned fundamental types.
241 241
242 typedef int underaligned_int __attribute__((packed,aligned(2))); 242 typedef int underaligned_int __attribute__((packed,aligned(2)));
243 underaligned_int underaligned_int_test() { 243 underaligned_int underaligned_int_test() {
244 // CHECK-LABEL: define i32 @underaligned_int_test() 244 // CHECK-LABEL: define{{.*}} i32 @underaligned_int_test()
245 return va_arg(the_list, underaligned_int); 245 return va_arg(the_list, underaligned_int);
246 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 246 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
247 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 247 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
248 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 248 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
249 249
276 // CHECK: ret i32 [[RESULT]] 276 // CHECK: ret i32 [[RESULT]]
277 } 277 }
278 278
279 typedef int overaligned_int __attribute__((aligned(32))); 279 typedef int overaligned_int __attribute__((aligned(32)));
280 overaligned_int overaligned_int_test() { 280 overaligned_int overaligned_int_test() {
281 // CHECK-LABEL: define i32 @overaligned_int_test() 281 // CHECK-LABEL: define{{.*}} i32 @overaligned_int_test()
282 return va_arg(the_list, overaligned_int); 282 return va_arg(the_list, overaligned_int);
283 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 283 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
284 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 284 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
285 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 285 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
286 286
313 // CHECK: ret i32 [[RESULT]] 313 // CHECK: ret i32 [[RESULT]]
314 } 314 }
315 315
316 typedef long long underaligned_long_long __attribute__((packed,aligned(2))); 316 typedef long long underaligned_long_long __attribute__((packed,aligned(2)));
317 underaligned_long_long underaligned_long_long_test() { 317 underaligned_long_long underaligned_long_long_test() {
318 // CHECK-LABEL: define i64 @underaligned_long_long_test() 318 // CHECK-LABEL: define{{.*}} i64 @underaligned_long_long_test()
319 return va_arg(the_list, underaligned_long_long); 319 return va_arg(the_list, underaligned_long_long);
320 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 320 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
321 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 321 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
322 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 322 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
323 323
346 // CHECK: ret i64 [[RESULT]] 346 // CHECK: ret i64 [[RESULT]]
347 } 347 }
348 348
349 typedef long long overaligned_long_long __attribute__((aligned(32))); 349 typedef long long overaligned_long_long __attribute__((aligned(32)));
350 overaligned_long_long overaligned_long_long_test() { 350 overaligned_long_long overaligned_long_long_test() {
351 // CHECK-LABEL: define i64 @overaligned_long_long_test() 351 // CHECK-LABEL: define{{.*}} i64 @overaligned_long_long_test()
352 return va_arg(the_list, overaligned_long_long); 352 return va_arg(the_list, overaligned_long_long);
353 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 353 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
354 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 354 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
355 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 355 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
356 356
379 // CHECK: ret i64 [[RESULT]] 379 // CHECK: ret i64 [[RESULT]]
380 } 380 }
381 381
382 typedef __int128 underaligned_int128 __attribute__((packed,aligned(2))); 382 typedef __int128 underaligned_int128 __attribute__((packed,aligned(2)));
383 underaligned_int128 underaligned_int128_test() { 383 underaligned_int128 underaligned_int128_test() {
384 // CHECK-LABEL: define i128 @underaligned_int128_test() 384 // CHECK-LABEL: define{{.*}} i128 @underaligned_int128_test()
385 return va_arg(the_list, underaligned_int128); 385 return va_arg(the_list, underaligned_int128);
386 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 386 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
387 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 387 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
388 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 388 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
389 389
418 // CHECK: ret i128 [[RESULT]] 418 // CHECK: ret i128 [[RESULT]]
419 } 419 }
420 420
421 typedef __int128 overaligned_int128 __attribute__((aligned(32))); 421 typedef __int128 overaligned_int128 __attribute__((aligned(32)));
422 overaligned_int128 overaligned_int128_test() { 422 overaligned_int128 overaligned_int128_test() {
423 // CHECK-LABEL: define i128 @overaligned_int128_test() 423 // CHECK-LABEL: define{{.*}} i128 @overaligned_int128_test()
424 return va_arg(the_list, overaligned_int128); 424 return va_arg(the_list, overaligned_int128);
425 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 425 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
426 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 426 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
427 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 427 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
428 428
471 471
472 typedef struct __attribute__((packed,aligned(2))) { 472 typedef struct __attribute__((packed,aligned(2))) {
473 int val; 473 int val;
474 } underaligned_int_struct; 474 } underaligned_int_struct;
475 underaligned_int_struct underaligned_int_struct_test() { 475 underaligned_int_struct underaligned_int_struct_test() {
476 // CHECK-LABEL: define i64 @underaligned_int_struct_test() 476 // CHECK-LE-LABEL: define{{.*}} i32 @underaligned_int_struct_test()
477 // CHECK-BE-LABEL: define{{.*}} i64 @underaligned_int_struct_test()
477 return va_arg(the_list, underaligned_int_struct); 478 return va_arg(the_list, underaligned_int_struct);
478 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 479 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
479 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 480 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
480 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 481 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
481 482
504 505
505 typedef struct __attribute__((aligned(16))) { 506 typedef struct __attribute__((aligned(16))) {
506 int val; 507 int val;
507 } overaligned_int_struct; 508 } overaligned_int_struct;
508 overaligned_int_struct overaligned_int_struct_test() { 509 overaligned_int_struct overaligned_int_struct_test() {
509 // CHECK-LABEL: define i128 @overaligned_int_struct_test() 510 // CHECK-LABEL: define{{.*}} i128 @overaligned_int_struct_test()
510 return va_arg(the_list, overaligned_int_struct); 511 return va_arg(the_list, overaligned_int_struct);
511 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 512 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
512 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 513 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
513 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 514 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
514 515
537 538
538 typedef struct __attribute__((packed,aligned(2))) { 539 typedef struct __attribute__((packed,aligned(2))) {
539 long long val; 540 long long val;
540 } underaligned_long_long_struct; 541 } underaligned_long_long_struct;
541 underaligned_long_long_struct underaligned_long_long_struct_test() { 542 underaligned_long_long_struct underaligned_long_long_struct_test() {
542 // CHECK-LABEL: define i64 @underaligned_long_long_struct_test() 543 // CHECK-LABEL: define{{.*}} i64 @underaligned_long_long_struct_test()
543 return va_arg(the_list, underaligned_long_long_struct); 544 return va_arg(the_list, underaligned_long_long_struct);
544 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 545 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
545 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 546 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
546 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 547 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
547 548
570 571
571 typedef struct __attribute__((aligned(16))) { 572 typedef struct __attribute__((aligned(16))) {
572 long long val; 573 long long val;
573 } overaligned_long_long_struct; 574 } overaligned_long_long_struct;
574 overaligned_long_long_struct overaligned_long_long_struct_test() { 575 overaligned_long_long_struct overaligned_long_long_struct_test() {
575 // CHECK-LABEL: define i128 @overaligned_long_long_struct_test() 576 // CHECK-LABEL: define{{.*}} i128 @overaligned_long_long_struct_test()
576 return va_arg(the_list, overaligned_long_long_struct); 577 return va_arg(the_list, overaligned_long_long_struct);
577 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 578 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
578 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 579 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
579 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 580 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
580 581
603 604
604 typedef struct __attribute__((packed,aligned(2))) { 605 typedef struct __attribute__((packed,aligned(2))) {
605 __int128 val; 606 __int128 val;
606 } underaligned_int128_struct; 607 } underaligned_int128_struct;
607 underaligned_int128_struct underaligned_int128_struct_test() { 608 underaligned_int128_struct underaligned_int128_struct_test() {
608 // CHECK-LABEL: define [2 x i64] @underaligned_int128_struct_test() 609 // CHECK-LABEL: define{{.*}} [2 x i64] @underaligned_int128_struct_test()
609 return va_arg(the_list, underaligned_int128_struct); 610 return va_arg(the_list, underaligned_int128_struct);
610 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 611 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
611 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 612 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
612 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 613 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
613 614
637 // Overaligning to 32 bytes causes it to be passed indirectly via a pointer 638 // Overaligning to 32 bytes causes it to be passed indirectly via a pointer
638 typedef struct __attribute__((aligned(32))) { 639 typedef struct __attribute__((aligned(32))) {
639 __int128 val; 640 __int128 val;
640 } overaligned_int128_struct; 641 } overaligned_int128_struct;
641 overaligned_int128_struct overaligned_int128_struct_test() { 642 overaligned_int128_struct overaligned_int128_struct_test() {
642 // CHECK-LABEL: define void @overaligned_int128_struct_test(%struct.overaligned_int128_struct* noalias sret align 32 %agg.result) 643 // CHECK-LABEL: define{{.*}} void @overaligned_int128_struct_test(%struct.overaligned_int128_struct* noalias sret(%struct.overaligned_int128_struct) align 32 %agg.result)
643 return va_arg(the_list, overaligned_int128_struct); 644 return va_arg(the_list, overaligned_int128_struct);
644 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 645 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
645 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 646 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
646 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 647 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
647 648
673 674
674 typedef struct { 675 typedef struct {
675 int val __attribute__((packed,aligned(2))); 676 int val __attribute__((packed,aligned(2)));
676 } underaligned_int_struct_member; 677 } underaligned_int_struct_member;
677 underaligned_int_struct_member underaligned_int_struct_member_test() { 678 underaligned_int_struct_member underaligned_int_struct_member_test() {
678 // CHECK-LABEL: define i64 @underaligned_int_struct_member_test() 679 // CHECK-LE-LABEL: define{{.*}} i32 @underaligned_int_struct_member_test()
680 // CHECK-BE-LABEL: define{{.*}} i64 @underaligned_int_struct_member_test()
679 return va_arg(the_list, underaligned_int_struct_member); 681 return va_arg(the_list, underaligned_int_struct_member);
680 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 682 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
681 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 683 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
682 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 684 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
683 685
706 708
707 typedef struct { 709 typedef struct {
708 int val __attribute__((aligned(16))); 710 int val __attribute__((aligned(16)));
709 } overaligned_int_struct_member; 711 } overaligned_int_struct_member;
710 overaligned_int_struct_member overaligned_int_struct_member_test() { 712 overaligned_int_struct_member overaligned_int_struct_member_test() {
711 // CHECK-LABEL: define i128 @overaligned_int_struct_member_test() 713 // CHECK-LABEL: define{{.*}} i128 @overaligned_int_struct_member_test()
712 return va_arg(the_list, overaligned_int_struct_member); 714 return va_arg(the_list, overaligned_int_struct_member);
713 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 715 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
714 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 716 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
715 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 717 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
716 718
745 747
746 typedef struct { 748 typedef struct {
747 long long val __attribute__((packed,aligned(2))); 749 long long val __attribute__((packed,aligned(2)));
748 } underaligned_long_long_struct_member; 750 } underaligned_long_long_struct_member;
749 underaligned_long_long_struct_member underaligned_long_long_struct_member_test() { 751 underaligned_long_long_struct_member underaligned_long_long_struct_member_test() {
750 // CHECK-LABEL: define i64 @underaligned_long_long_struct_member_test() 752 // CHECK-LABEL: define{{.*}} i64 @underaligned_long_long_struct_member_test()
751 return va_arg(the_list, underaligned_long_long_struct_member); 753 return va_arg(the_list, underaligned_long_long_struct_member);
752 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 754 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
753 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 755 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
754 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 756 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
755 757
778 780
779 typedef struct { 781 typedef struct {
780 long long val __attribute__((aligned(16))); 782 long long val __attribute__((aligned(16)));
781 } overaligned_long_long_struct_member; 783 } overaligned_long_long_struct_member;
782 overaligned_long_long_struct_member overaligned_long_long_struct_member_test() { 784 overaligned_long_long_struct_member overaligned_long_long_struct_member_test() {
783 // CHECK-LABEL: define i128 @overaligned_long_long_struct_member_test() 785 // CHECK-LABEL: define{{.*}} i128 @overaligned_long_long_struct_member_test()
784 return va_arg(the_list, overaligned_long_long_struct_member); 786 return va_arg(the_list, overaligned_long_long_struct_member);
785 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 787 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
786 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 788 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
787 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 789 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
788 790
817 819
818 typedef struct { 820 typedef struct {
819 __int128 val __attribute__((packed,aligned(2))); 821 __int128 val __attribute__((packed,aligned(2)));
820 } underaligned_int128_struct_member; 822 } underaligned_int128_struct_member;
821 underaligned_int128_struct_member underaligned_int128_struct_member_test() { 823 underaligned_int128_struct_member underaligned_int128_struct_member_test() {
822 // CHECK-LABEL: define [2 x i64] @underaligned_int128_struct_member_test() 824 // CHECK-LABEL: define{{.*}} [2 x i64] @underaligned_int128_struct_member_test()
823 return va_arg(the_list, underaligned_int128_struct_member); 825 return va_arg(the_list, underaligned_int128_struct_member);
824 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 826 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
825 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 827 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
826 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 828 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
827 829
851 // Overaligning to 32 bytes causes it to be passed indirectly via a pointer 853 // Overaligning to 32 bytes causes it to be passed indirectly via a pointer
852 typedef struct { 854 typedef struct {
853 __int128 val __attribute__((aligned(32))); 855 __int128 val __attribute__((aligned(32)));
854 } overaligned_int128_struct_member; 856 } overaligned_int128_struct_member;
855 overaligned_int128_struct_member overaligned_int128_struct_member_test() { 857 overaligned_int128_struct_member overaligned_int128_struct_member_test() {
856 // CHECK-LABEL: define void @overaligned_int128_struct_member_test(%struct.overaligned_int128_struct_member* noalias sret align 32 %agg.result) 858 // CHECK-LABEL: define{{.*}} void @overaligned_int128_struct_member_test(%struct.overaligned_int128_struct_member* noalias sret(%struct.overaligned_int128_struct_member) align 32 %agg.result)
857 return va_arg(the_list, overaligned_int128_struct_member); 859 return va_arg(the_list, overaligned_int128_struct_member);
858 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3) 860 // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
859 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 861 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
860 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]] 862 // CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG:[a-z_.0-9]+]]
861 863
881 // CHECK: [[VAARG_END]] 883 // CHECK: [[VAARG_END]]
882 // CHECK: [[ADDR:%[a-z._0-9]+]] = phi %struct.overaligned_int128_struct_member** [ [[FROMREG_ADDR]], %[[VAARG_IN_REG]] ], [ [[FROMSTACK_ADDR]], %[[VAARG_ON_STACK]] ] 884 // CHECK: [[ADDR:%[a-z._0-9]+]] = phi %struct.overaligned_int128_struct_member** [ [[FROMREG_ADDR]], %[[VAARG_IN_REG]] ], [ [[FROMSTACK_ADDR]], %[[VAARG_ON_STACK]] ]
883 } 885 }
884 886
885 void check_start(int n, ...) { 887 void check_start(int n, ...) {
886 // CHECK-LABEL: define void @check_start(i32 %n, ...) 888 // CHECK-LABEL: define{{.*}} void @check_start(i32 %n, ...)
887 889
888 va_list the_list; 890 va_list the_list;
889 va_start(the_list, n); 891 va_start(the_list, n);
890 // CHECK: [[THE_LIST:%[a-z_0-9]+]] = alloca %struct.__va_list 892 // CHECK: [[THE_LIST:%[a-z_0-9]+]] = alloca %struct.__va_list
891 // CHECK: [[VOIDP_THE_LIST:%[a-z_0-9]+]] = bitcast %struct.__va_list* [[THE_LIST]] to i8* 893 // CHECK: [[VOIDP_THE_LIST:%[a-z_0-9]+]] = bitcast %struct.__va_list* [[THE_LIST]] to i8*