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