1 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -debug-info-kind=limited -Wno-strict-prototypes -o - %s | \
2 // RUN: FileCheck %s -check-prefix=CHECK -check-prefix=SSE -check-prefix=NO-AVX512
3 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -debug-info-kind=limited -Wno-strict-prototypes -o - %s -target-feature +avx | \
4 // RUN: FileCheck %s -check-prefix=CHECK -check-prefix=AVX -check-prefix=NO-AVX512
5 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -debug-info-kind=limited -Wno-strict-prototypes -o - %s -target-feature +avx512f | \
6 // RUN: FileCheck %s -check-prefix=CHECK -check-prefix=AVX -check-prefix=AVX512
7 #include <stdarg.h>
8
9 // CHECK-LABEL: define{{.*}} signext i8 @f0()
f0(void)10 char f0(void) {
11 return 0;
12 }
13
14 // CHECK-LABEL: define{{.*}} signext i16 @f1()
f1(void)15 short f1(void) {
16 return 0;
17 }
18
19 // CHECK-LABEL: define{{.*}} i32 @f2()
f2(void)20 int f2(void) {
21 return 0;
22 }
23
24 // CHECK-LABEL: define{{.*}} float @f3()
f3(void)25 float f3(void) {
26 return 0;
27 }
28
29 // CHECK-LABEL: define{{.*}} double @f4()
f4(void)30 double f4(void) {
31 return 0;
32 }
33
34 // CHECK-LABEL: define{{.*}} x86_fp80 @f5()
f5(void)35 long double f5(void) {
36 return 0;
37 }
38
39 // CHECK-LABEL: define{{.*}} void @f6(i8 noundef signext %a0, i16 noundef signext %a1, i32 noundef %a2, i64 noundef %a3, ptr noundef %a4)
f6(char a0,short a1,int a2,long long a3,void * a4)40 void f6(char a0, short a1, int a2, long long a3, void *a4) {
41 }
42
43 // CHECK-LABEL: define{{.*}} void @f7(i32 noundef %a0)
44 typedef enum { A, B, C } e7;
f7(e7 a0)45 void f7(e7 a0) {
46 }
47
48 // Test merging/passing of upper eightbyte with X87 class.
49 //
50 // CHECK-LABEL: define{{.*}} void @f8_1(ptr dead_on_unwind noalias writable sret(%union.u8) align 16 %agg.result)
51 // CHECK-LABEL: define{{.*}} void @f8_2(ptr noundef byval(%union.u8) align 16 %a0)
52 union u8 {
53 long double a;
54 int b;
55 };
f8_1(void)56 union u8 f8_1(void) { while (1) {} }
f8_2(union u8 a0)57 void f8_2(union u8 a0) {}
58
59 // CHECK-LABEL: define{{.*}} i64 @f9()
f9(void)60 struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} }
61
62 // CHECK-LABEL: define{{.*}} void @f10(i64 %a0.coerce)
63 struct s10 { int a; int b; int : 0; };
f10(struct s10 a0)64 void f10(struct s10 a0) {}
65
66 // CHECK-LABEL: define{{.*}} void @f11(ptr dead_on_unwind noalias writable sret(%union.anon) align 16 %agg.result)
f11(void)67 union { long double a; float b; } f11(void) { while (1) {} }
68
69 // CHECK-LABEL: define{{.*}} i32 @f12_0()
70 // CHECK-LABEL: define{{.*}} void @f12_1(i32 %a0.coerce)
71 struct s12 { int a __attribute__((aligned(16))); };
f12_0(void)72 struct s12 f12_0(void) { while (1) {} }
f12_1(struct s12 a0)73 void f12_1(struct s12 a0) {}
74
75 // Check that sret parameter is accounted for when checking available integer
76 // registers.
77 // CHECK: define{{.*}} void @f13(ptr dead_on_unwind noalias writable sret(%struct.s13_0) align 8 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, ptr noundef byval({{.*}}) align 8 %e, i32 noundef %f)
78
79 struct s13_0 { long long f0[3]; };
80 struct s13_1 { long long f0[2]; };
f13(int a,int b,int c,int d,struct s13_1 e,int f)81 struct s13_0 f13(int a, int b, int c, int d,
82 struct s13_1 e, int f) { while (1) {} }
83
84 // CHECK: define{{.*}} void @f14({{.*}}, i8 noundef signext %X)
f14(int a,int b,int c,int d,int e,int f,char X)85 void f14(int a, int b, int c, int d, int e, int f, char X) {}
86
87 // CHECK: define{{.*}} void @f15({{.*}}, ptr noundef %X)
f15(int a,int b,int c,int d,int e,int f,void * X)88 void f15(int a, int b, int c, int d, int e, int f, void *X) {}
89
90 // CHECK: define{{.*}} void @f16({{.*}}, float noundef %X)
f16(float a,float b,float c,float d,float e,float f,float g,float h,float X)91 void f16(float a, float b, float c, float d, float e, float f, float g, float h,
92 float X) {}
93
94 // CHECK: define{{.*}} void @f17({{.*}}, x86_fp80 noundef %X)
f17(float a,float b,float c,float d,float e,float f,float g,float h,long double X)95 void f17(float a, float b, float c, float d, float e, float f, float g, float h,
96 long double X) {}
97
98 // Check for valid coercion. The struct should be passed/returned as i32, not
99 // as i64 for better code quality.
100 // CHECK-LABEL: define{{.*}} void @f18(i32 noundef %a, i32 %f18_arg1.coerce)
101 struct f18_s0 { int f0; };
f18(int a,struct f18_s0 f18_arg1)102 void f18(int a, struct f18_s0 f18_arg1) { while (1) {} }
103
104 // Check byval alignment.
105
106 // CHECK-LABEL: define{{.*}} void @f19(ptr noundef byval(%struct.s19) align 16 %x)
107 struct s19 {
108 long double a;
109 };
f19(struct s19 x)110 void f19(struct s19 x) {}
111
112 // CHECK-LABEL: define{{.*}} void @f20(ptr noundef byval(%struct.s20) align 32 %x)
113 struct __attribute__((aligned(32))) s20 {
114 int x;
115 int y;
116 };
f20(struct s20 x)117 void f20(struct s20 x) {}
118
119 struct StringRef {
120 long x;
121 const char *Ptr;
122 };
123
124 // CHECK-LABEL: define{{.*}} ptr @f21(i64 %S.coerce0, ptr %S.coerce1)
f21(struct StringRef S)125 const char *f21(struct StringRef S) { return S.x+S.Ptr; }
126
127 // PR7567
128 typedef __attribute__ ((aligned(16))) struct f22s { unsigned long long x[2]; } L;
f22(L x,L y)129 void f22(L x, L y) { }
130 // CHECK: @f22
131 // CHECK: %x = alloca{{.*}}, align 16
132 // CHECK: %y = alloca{{.*}}, align 16
133
134
135
136 // PR7714
137 struct f23S {
138 short f0;
139 unsigned f1;
140 int f2;
141 };
142
143
f23(int A,struct f23S B)144 void f23(int A, struct f23S B) {
145 // CHECK-LABEL: define{{.*}} void @f23(i32 noundef %A, i64 %B.coerce0, i32 %B.coerce1)
146 }
147
148 struct f24s { long a; int b; };
149
f24(struct f23S * X,struct f24s * P2)150 struct f23S f24(struct f23S *X, struct f24s *P2) {
151 return *X;
152
153 // CHECK: define{{.*}} { i64, i32 } @f24(ptr noundef %X, ptr noundef %P2)
154 }
155
156 typedef float v4f32 __attribute__((__vector_size__(16)));
f25(v4f32 X)157 v4f32 f25(v4f32 X) {
158 // CHECK-LABEL: define{{.*}} <4 x float> @f25(<4 x float> noundef %X)
159 // CHECK-NOT: alloca
160 // CHECK: alloca <4 x float>
161 // CHECK-NOT: alloca
162 // CHECK: store <4 x float> %X, ptr
163 // CHECK-NOT: store
164 // CHECK: ret <4 x float>
165 return X+X;
166 }
167
168 struct foo26 {
169 int *X;
170 float *Y;
171 };
172
f26(struct foo26 * P)173 struct foo26 f26(struct foo26 *P) {
174 // CHECK: define{{.*}} { ptr, ptr } @f26(ptr noundef %P)
175 return *P;
176 }
177
178
179 struct v4f32wrapper {
180 v4f32 v;
181 };
182
f27(struct v4f32wrapper X)183 struct v4f32wrapper f27(struct v4f32wrapper X) {
184 // CHECK-LABEL: define{{.*}} <4 x float> @f27(<4 x float> %X.coerce)
185 return X;
186 }
187
188 // PR22563 - We should unwrap simple structs and arrays to pass
189 // and return them in the appropriate vector registers if possible.
190
191 typedef float v8f32 __attribute__((__vector_size__(32)));
192 struct v8f32wrapper {
193 v8f32 v;
194 };
195
f27a(struct v8f32wrapper X)196 struct v8f32wrapper f27a(struct v8f32wrapper X) {
197 // AVX-LABEL: define{{.*}} <8 x float> @f27a(<8 x float> %X.coerce)
198 return X;
199 }
200
201 struct v8f32wrapper_wrapper {
202 v8f32 v[1];
203 };
204
f27b(struct v8f32wrapper_wrapper X)205 struct v8f32wrapper_wrapper f27b(struct v8f32wrapper_wrapper X) {
206 // AVX-LABEL: define{{.*}} <8 x float> @f27b(<8 x float> %X.coerce)
207 return X;
208 }
209
210 struct f28c {
211 double x;
212 int y;
213 };
f28(struct f28c C)214 void f28(struct f28c C) {
215 // CHECK-LABEL: define{{.*}} void @f28(double %C.coerce0, i32 %C.coerce1)
216 }
217
218 struct f29a {
219 struct c {
220 double x;
221 int y;
222 } x[1];
223 };
224
f29a(struct f29a A)225 void f29a(struct f29a A) {
226 // CHECK-LABEL: define{{.*}} void @f29a(double %A.coerce0, i32 %A.coerce1)
227 }
228
229 struct S0 { char f0[8]; char f2; char f3; char f4; };
f30(struct S0 p_4)230 void f30(struct S0 p_4) {
231 // CHECK-LABEL: define{{.*}} void @f30(i64 %p_4.coerce0, i24 %p_4.coerce1)
232 }
233
234 // Pass the third element as a float when followed by tail padding.
235 struct f31foo { float a, b, c; };
f31(struct f31foo X)236 float f31(struct f31foo X) {
237 // CHECK-LABEL: define{{.*}} float @f31(<2 x float> %X.coerce0, float %X.coerce1)
238 return X.c;
239 }
240
f32(_Complex float A,_Complex float B)241 _Complex float f32(_Complex float A, _Complex float B) {
242 // CHECK-LABEL: define{{.*}} <2 x float> @f32(<2 x float> noundef %A.coerce, <2 x float> noundef %B.coerce)
243 return A+B;
244 }
245
246 struct f33s { long x; float c,d; };
247
f33(va_list X)248 void f33(va_list X) {
249 va_arg(X, struct f33s);
250 }
251
252 typedef unsigned long long v1i64 __attribute__((__vector_size__(8)));
253
254 // CHECK-LABEL: define{{.*}} double @f34(double noundef %arg.coerce)
f34(v1i64 arg)255 v1i64 f34(v1i64 arg) { return arg; }
256
257 // CHECK-LABEL: define{{.*}} double @f35(double noundef %arg.coerce)
258 typedef unsigned long v1i64_2 __attribute__((__vector_size__(8)));
f35(v1i64_2 arg)259 v1i64_2 f35(v1i64_2 arg) { return arg+arg; }
260
261 // CHECK: declare void @func(ptr noundef byval(%struct._str) align 16)
262 typedef struct _str {
263 union {
264 long double a;
265 long c;
266 };
267 } str;
268
269 void func(str s);
270 str ss;
f9122143(void)271 void f9122143(void)
272 {
273 func(ss);
274 }
275
276 // CHECK-LABEL: define{{.*}} double @f36(double noundef %arg.coerce)
277 typedef unsigned v2i32 __attribute((__vector_size__(8)));
f36(v2i32 arg)278 v2i32 f36(v2i32 arg) { return arg; }
279
280 // AVX: declare void @f38(<8 x float>)
281 // AVX: declare void @f37(<8 x float> noundef)
282 // SSE: declare void @f38(ptr noundef byval(%struct.s256) align 32)
283 // SSE: declare void @f37(ptr noundef byval(<8 x float>) align 32)
284 typedef float __m256 __attribute__ ((__vector_size__ (32)));
285 typedef struct {
286 __m256 m;
287 } s256;
288
289 s256 x38;
290 __m256 x37;
291
292 void f38(s256 x);
293 void f37(__m256 x);
f39(void)294 void f39(void) { f38(x38); f37(x37); }
295
296 // The two next tests make sure that the struct below is passed
297 // in the same way regardless of avx being used
298
299 // CHECK: declare void @func40(ptr noundef byval(%struct.t128) align 16)
300 typedef float __m128 __attribute__ ((__vector_size__ (16)));
301 typedef struct t128 {
302 __m128 m;
303 __m128 n;
304 } two128;
305
306 extern void func40(two128 s);
func41(two128 s)307 void func41(two128 s) {
308 func40(s);
309 }
310
311 // CHECK: declare void @func42(ptr noundef byval(%struct.t128_2) align 16)
312 typedef struct xxx {
313 __m128 array[2];
314 } Atwo128;
315 typedef struct t128_2 {
316 Atwo128 x;
317 } SA;
318
319 extern void func42(SA s);
func43(SA s)320 void func43(SA s) {
321 func42(s);
322 }
323
324 // CHECK-LABEL: define{{.*}} i32 @f44
325 // CHECK: getelementptr inbounds i8, ptr %{{.+}}, i32 31
326 // CHECK-NEXT: call ptr @llvm.ptrmask.p0.i64(ptr %{{[0-9]+}}, i64 -32)
327 typedef int T44 __attribute((vector_size(32)));
328 struct s44 { T44 x; int y; };
f44(int i,...)329 int f44(int i, ...) {
330 __builtin_va_list ap;
331 __builtin_va_start(ap, i);
332 struct s44 s = __builtin_va_arg(ap, struct s44);
333 __builtin_va_end(ap);
334 return s.y;
335 }
336
337 // Text that vec3 returns the correct LLVM IR type.
338 // AVX-LABEL: define{{.*}} i32 @foo(<3 x i64> noundef %X)
339 typedef long long3 __attribute((ext_vector_type(3)));
foo(long3 X)340 int foo(long3 X)
341 {
342 return 0;
343 }
344
345 // Make sure we don't use a varargs convention for a function without a
346 // prototype where AVX types are involved.
347 // AVX: @test45
348 // AVX: call i32 @f45
349 int f45();
350 __m256 x45;
test45(void)351 void test45(void) { f45(x45); }
352
353 // Make sure we use byval to pass 64-bit vectors in memory; the LLVM call
354 // lowering can't handle this case correctly because it runs after legalization.
355 // CHECK: @test46
356 // CHECK: call void @f46({{.*}}ptr noundef byval(<2 x float>) align 8 {{.*}}, ptr noundef byval(<2 x float>) align 8 {{.*}})
357 typedef float v46 __attribute((vector_size(8)));
358 void f46(v46,v46,v46,v46,v46,v46,v46,v46,v46,v46);
test46(void)359 void test46(void) { v46 x = {1,2}; f46(x,x,x,x,x,x,x,x,x,x); }
360
361 // Check that we pass the struct below without using byval, which helps out
362 // codegen.
363 //
364 // CHECK: @test47
365 // CHECK: call void @f47(i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}})
366 struct s47 { unsigned a; };
367 void f47(int,int,int,int,int,int,struct s47);
test47(int a,struct s47 b)368 void test47(int a, struct s47 b) { f47(a, a, a, a, a, a, b); }
369
370 // In the following example, there are holes in T4 at the 3rd byte and the 4th
371 // byte, however, T2 does not have those holes. T4 is chosen to be the
372 // representing type for union T1, but we can't use load or store of T4 since
373 // it will skip the 3rd byte and the 4th byte.
374 // In general, Since we don't accurately represent the data fields of a union,
375 // do not use load or store of the representing llvm type for the union.
376 typedef _Complex int T2;
377 typedef _Complex char T5;
378 typedef _Complex int T7;
379 typedef struct T4 { T5 field0; T7 field1; } T4;
380 typedef union T1 { T2 field0; T4 field1; } T1;
381 extern T1 T1_retval;
test48(void)382 T1 test48(void) {
383 // CHECK: @test48
384 // CHECK: memcpy
385 // CHECK: memcpy
386 return T1_retval;
387 }
388
389 void test49_helper(double, ...);
test49(double d,double e)390 void test49(double d, double e) {
391 test49_helper(d, e);
392 }
393 // CHECK-LABEL: define{{.*}} void @test49(
394 // CHECK: [[T0:%.*]] = load double, ptr
395 // CHECK-NEXT: [[T1:%.*]] = load double, ptr
396 // CHECK-NEXT: call void (double, ...) @test49_helper(double noundef [[T0]], double noundef [[T1]])
397
398 void test50_helper();
test50(double d,double e)399 void test50(double d, double e) {
400 test50_helper(d, e);
401 }
402 // CHECK-LABEL: define{{.*}} void @test50(
403 // CHECK: [[T0:%.*]] = load double, ptr
404 // CHECK-NEXT: [[T1:%.*]] = load double, ptr
405 // CHECK-NEXT: call void (double, double, ...) @test50_helper(double noundef [[T0]], double noundef [[T1]])
406
407 struct test51_s { __uint128_t intval; };
test51(struct test51_s * s,__builtin_va_list argList)408 void test51(struct test51_s *s, __builtin_va_list argList) {
409 *s = __builtin_va_arg(argList, struct test51_s);
410 }
411
412 // CHECK-LABEL: define{{.*}} void @test51
413 // CHECK: [[TMP_ADDR:%.*]] = alloca [[STRUCT_TEST51:%.*]], align 16
414 // CHECK: br i1
415 // CHECK: [[REG_SAVE_AREA_PTR:%.*]] = getelementptr inbounds {{.*}}, i32 0, i32 3
416 // CHECK-NEXT: [[REG_SAVE_AREA:%.*]] = load ptr, ptr [[REG_SAVE_AREA_PTR]]
417 // CHECK-NEXT: [[VALUE_ADDR:%.*]] = getelementptr i8, ptr [[REG_SAVE_AREA]], i32 {{.*}}
418 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 16 [[TMP_ADDR]], ptr align 8 [[VALUE_ADDR]], i64 16, i1 false)
419 // CHECK-NEXT: add i32 {{.*}}, 16
420 // CHECK-NEXT: store i32 {{.*}}, ptr {{.*}}
421 // CHECK-NEXT: br label
422
423 void test52_helper(int, ...);
424 __m256 x52;
test52(void)425 void test52(void) {
426 test52_helper(0, x52, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0i);
427 }
428 // AVX: @test52_helper(i32 noundef 0, <8 x float> noundef {{%[a-zA-Z0-9]+}}, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef {{%[a-zA-Z0-9]+}}, double noundef {{%[a-zA-Z0-9]+}})
429
test53(__m256 * m,__builtin_va_list argList)430 void test53(__m256 *m, __builtin_va_list argList) {
431 *m = __builtin_va_arg(argList, __m256);
432 }
433 // AVX-LABEL: define{{.*}} void @test53
434 // AVX-NOT: br i1
435 // AVX: ret void
436
437 void test54_helper(__m256, ...);
438 __m256 x54;
test54(void)439 void test54(void) {
440 test54_helper(x54, x54, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0i);
441 test54_helper(x54, x54, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0i);
442 }
443 // AVX: @test54_helper(<8 x float> noundef {{%[a-zA-Z0-9]+}}, <8 x float> noundef {{%[a-zA-Z0-9]+}}, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef {{%[a-zA-Z0-9]+}}, double noundef {{%[a-zA-Z0-9]+}})
444 // AVX: @test54_helper(<8 x float> noundef {{%[a-zA-Z0-9]+}}, <8 x float> noundef {{%[a-zA-Z0-9]+}}, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, ptr noundef byval({ double, double }) align 8 {{%[^)]+}})
445
446 typedef float __m512 __attribute__ ((__vector_size__ (64)));
447 typedef struct {
448 __m512 m;
449 } s512;
450
451 s512 x55;
452 __m512 x56;
453
454 // On AVX512, aggregates which contain a __m512 type are classified as SSE/SSEUP
455 // as per https://github.com/hjl-tools/x86-psABI/commit/30f9c9 3.2.3p2 Rule 1
456 //
457 // AVX512: declare void @f55(<16 x float>)
458 // NO-AVX512: declare void @f55(ptr noundef byval(%struct.s512) align 64)
459 void f55(s512 x);
460
461 // __m512 has type SSE/SSEUP on AVX512.
462 //
463 // AVX512: declare void @f56(<16 x float> noundef)
464 // NO-AVX512: declare void @f56(ptr noundef byval(<16 x float>) align 64)
465 void f56(__m512 x);
f57(void)466 void f57(void) { f55(x55); f56(x56); }
467
468 // Like for __m128 on AVX, check that the struct below is passed
469 // in the same way regardless of AVX512 being used.
470 //
471 // CHECK: declare void @f58(ptr noundef byval(%struct.t256) align 32)
472 typedef struct t256 {
473 __m256 m;
474 __m256 n;
475 } two256;
476
477 extern void f58(two256 s);
f59(two256 s)478 void f59(two256 s) {
479 f58(s);
480 }
481
482 // CHECK: declare void @f60(ptr noundef byval(%struct.sat256) align 32)
483 typedef struct at256 {
484 __m256 array[2];
485 } Atwo256;
486 typedef struct sat256 {
487 Atwo256 x;
488 } SAtwo256;
489
490 extern void f60(SAtwo256 s);
f61(SAtwo256 s)491 void f61(SAtwo256 s) {
492 f60(s);
493 }
494
495 // AVX512: @f62_helper(i32 noundef 0, <16 x float> noundef {{%[a-zA-Z0-9]+}}, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef {{%[a-zA-Z0-9]+}}, double noundef {{%[a-zA-Z0-9]+}})
496 void f62_helper(int, ...);
497 __m512 x62;
f62(void)498 void f62(void) {
499 f62_helper(0, x62, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0i);
500 }
501
502 // Like for __m256 on AVX, we always pass __m512 in memory, and don't
503 // need to use the register save area.
504 //
505 // AVX512-LABEL: define{{.*}} void @f63
506 // AVX512-NOT: br i1
507 // AVX512: ret void
f63(__m512 * m,__builtin_va_list argList)508 void f63(__m512 *m, __builtin_va_list argList) {
509 *m = __builtin_va_arg(argList, __m512);
510 }
511
512 // AVX512: @f64_helper(<16 x float> noundef {{%[a-zA-Z0-9]+}}, <16 x float> noundef {{%[a-zA-Z0-9]+}}, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef {{%[a-zA-Z0-9]+}}, double noundef {{%[a-zA-Z0-9]+}})
513 // AVX512: @f64_helper(<16 x float> noundef {{%[a-zA-Z0-9]+}}, <16 x float> noundef {{%[a-zA-Z0-9]+}}, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, double noundef 1.000000e+00, ptr noundef byval({ double, double }) align 8 {{%[^)]+}})
514 void f64_helper(__m512, ...);
515 __m512 x64;
f64(void)516 void f64(void) {
517 f64_helper(x64, x64, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0i);
518 f64_helper(x64, x64, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0i);
519 }
520
521 struct t65 {
522 __m256 m;
523 int : 0;
524 };
525 // SSE-LABEL: @f65(ptr noundef byval(%struct.t65) align 32 %{{[^,)]+}})
526 // AVX: @f65(<8 x float> %{{[^,)]+}})
f65(struct t65 a0)527 void f65(struct t65 a0) {
528 }
529
530 typedef float t66 __attribute__((__vector_size__(128), __aligned__(128)));
531
532 // AVX512: @f66(ptr noundef byval(<32 x float>) align 128 %0)
f66(t66 a0)533 void f66(t66 a0) {
534 }
535
536 typedef long long t67 __attribute__((aligned (4)));
537 struct s67 {
538 int a;
539 t67 b;
540 };
541 // CHECK-LABEL: define{{.*}} void @f67(ptr noundef byval(%struct.s67) align 8 %x)
f67(struct s67 x)542 void f67(struct s67 x) {
543 }
544
545 typedef double t68 __attribute__((aligned (4)));
546 struct s68 {
547 int a;
548 t68 b;
549 };
550 // CHECK-LABEL: define{{.*}} void @f68(ptr noundef byval(%struct.s68) align 8 %x)
f68(struct s68 x)551 void f68(struct s68 x) {
552 }
553
554 /// The synthesized __va_list_tag does not have file/line fields.
555 // CHECK: = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "__va_list_tag",
556 // CHECK-NOT: file:
557 // CHECK-NOT: line:
558 // CHECK-SAME: size:
559