1 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s| FileCheck %s
2 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-feature +avx | FileCheck %s -check-prefix=AVX
3 #include <stdarg.h>
4
5 // CHECK: define signext i8 @f0()
f0(void)6 char f0(void) {
7 return 0;
8 }
9
10 // CHECK: define signext i16 @f1()
f1(void)11 short f1(void) {
12 return 0;
13 }
14
15 // CHECK: define i32 @f2()
f2(void)16 int f2(void) {
17 return 0;
18 }
19
20 // CHECK: define float @f3()
f3(void)21 float f3(void) {
22 return 0;
23 }
24
25 // CHECK: define double @f4()
f4(void)26 double f4(void) {
27 return 0;
28 }
29
30 // CHECK: define x86_fp80 @f5()
f5(void)31 long double f5(void) {
32 return 0;
33 }
34
35 // CHECK: 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)36 void f6(char a0, short a1, int a2, long long a3, void *a4) {
37 }
38
39 // CHECK: define void @f7(i32 %a0)
40 typedef enum { A, B, C } e7;
f7(e7 a0)41 void f7(e7 a0) {
42 }
43
44 // Test merging/passing of upper eightbyte with X87 class.
45 //
46 // CHECK: define void @f8_1(%union.u8* noalias sret %agg.result)
47 // CHECK: define void @f8_2(%union.u8* byval align 16 %a0)
48 union u8 {
49 long double a;
50 int b;
51 };
f8_1()52 union u8 f8_1() { while (1) {} }
f8_2(union u8 a0)53 void f8_2(union u8 a0) {}
54
55 // CHECK: define i64 @f9()
f9(void)56 struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} }
57
58 // CHECK: define void @f10(i64 %a0.coerce)
59 struct s10 { int a; int b; int : 0; };
f10(struct s10 a0)60 void f10(struct s10 a0) {}
61
62 // CHECK: define void @f11(%union.anon* noalias sret %agg.result)
f11()63 union { long double a; float b; } f11() { while (1) {} }
64
65 // CHECK: define i32 @f12_0()
66 // CHECK: define void @f12_1(i32 %a0.coerce)
67 struct s12 { int a __attribute__((aligned(16))); };
f12_0(void)68 struct s12 f12_0(void) { while (1) {} }
f12_1(struct s12 a0)69 void f12_1(struct s12 a0) {}
70
71 // Check that sret parameter is accounted for when checking available integer
72 // registers.
73 // 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)
74
75 struct s13_0 { long long f0[3]; };
76 struct s13_1 { long long f0[2]; };
f13(int a,int b,int c,int d,struct s13_1 e,int f)77 struct s13_0 f13(int a, int b, int c, int d,
78 struct s13_1 e, int f) { while (1) {} }
79
80 // CHECK: define void @f14({{.*}}, i8 signext %X)
f14(int a,int b,int c,int d,int e,int f,char X)81 void f14(int a, int b, int c, int d, int e, int f, char X) {}
82
83 // CHECK: define void @f15({{.*}}, i8* %X)
f15(int a,int b,int c,int d,int e,int f,void * X)84 void f15(int a, int b, int c, int d, int e, int f, void *X) {}
85
86 // 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)87 void f16(float a, float b, float c, float d, float e, float f, float g, float h,
88 float X) {}
89
90 // 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)91 void f17(float a, float b, float c, float d, float e, float f, float g, float h,
92 long double X) {}
93
94 // Check for valid coercion. The struct should be passed/returned as i32, not
95 // as i64 for better code quality.
96 // rdar://8135035
97 // CHECK: define void @f18(i32 %a, i32 %f18_arg1.coerce)
98 struct f18_s0 { int f0; };
f18(int a,struct f18_s0 f18_arg1)99 void f18(int a, struct f18_s0 f18_arg1) { while (1) {} }
100
101 // Check byval alignment.
102
103 // CHECK: define void @f19(%struct.s19* byval align 16 %x)
104 struct s19 {
105 long double a;
106 };
f19(struct s19 x)107 void f19(struct s19 x) {}
108
109 // CHECK: define void @f20(%struct.s20* byval align 32 %x)
110 struct __attribute__((aligned(32))) s20 {
111 int x;
112 int y;
113 };
f20(struct s20 x)114 void f20(struct s20 x) {}
115
116 struct StringRef {
117 long x;
118 const char *Ptr;
119 };
120
121 // rdar://7375902
122 // CHECK: define i8* @f21(i64 %S.coerce0, i8* %S.coerce1)
f21(struct StringRef S)123 const char *f21(struct StringRef S) { return S.x+S.Ptr; }
124
125 // PR7567
126 typedef __attribute__ ((aligned(16))) struct f22s { unsigned long long x[2]; } L;
f22(L x,L y)127 void f22(L x, L y) { }
128 // CHECK: @f22
129 // CHECK: %x = alloca{{.*}}, align 16
130 // CHECK: %y = alloca{{.*}}, align 16
131
132
133
134 // PR7714
135 struct f23S {
136 short f0;
137 unsigned f1;
138 int f2;
139 };
140
141
f23(int A,struct f23S B)142 void f23(int A, struct f23S B) {
143 // CHECK: define void @f23(i32 %A, i64 %B.coerce0, i32 %B.coerce1)
144 }
145
146 struct f24s { long a; int b; };
147
f24(struct f23S * X,struct f24s * P2)148 struct f23S f24(struct f23S *X, struct f24s *P2) {
149 return *X;
150
151 // CHECK: define { i64, i32 } @f24(%struct.f23S* %X, %struct.f24s* %P2)
152 }
153
154 // rdar://8248065
155 typedef float v4f32 __attribute__((__vector_size__(16)));
f25(v4f32 X)156 v4f32 f25(v4f32 X) {
157 // CHECK: define <4 x float> @f25(<4 x float> %X)
158 // CHECK-NOT: alloca
159 // CHECK: alloca <4 x float>
160 // CHECK-NOT: alloca
161 // CHECK: store <4 x float> %X, <4 x float>*
162 // CHECK-NOT: store
163 // CHECK: ret <4 x float>
164 return X+X;
165 }
166
167 struct foo26 {
168 int *X;
169 float *Y;
170 };
171
f26(struct foo26 * P)172 struct foo26 f26(struct foo26 *P) {
173 // CHECK: define { i32*, float* } @f26(%struct.foo26* %P)
174 return *P;
175 }
176
177
178 struct v4f32wrapper {
179 v4f32 v;
180 };
181
f27(struct v4f32wrapper X)182 struct v4f32wrapper f27(struct v4f32wrapper X) {
183 // CHECK: define <4 x float> @f27(<4 x float> %X.coerce)
184 return X;
185 }
186
187 // rdar://5711709
188 struct f28c {
189 double x;
190 int y;
191 };
f28(struct f28c C)192 void f28(struct f28c C) {
193 // CHECK: define void @f28(double %C.coerce0, i32 %C.coerce1)
194 }
195
196 struct f29a {
197 struct c {
198 double x;
199 int y;
200 } x[1];
201 };
202
f29a(struct f29a A)203 void f29a(struct f29a A) {
204 // CHECK: define void @f29a(double %A.coerce0, i32 %A.coerce1)
205 }
206
207 // rdar://8249586
208 struct S0 { char f0[8]; char f2; char f3; char f4; };
f30(struct S0 p_4)209 void f30(struct S0 p_4) {
210 // CHECK: define void @f30(i64 %p_4.coerce0, i24 %p_4.coerce1)
211 }
212
213 // Pass the third element as a float when followed by tail padding.
214 // rdar://8251384
215 struct f31foo { float a, b, c; };
f31(struct f31foo X)216 float f31(struct f31foo X) {
217 // CHECK: define float @f31(<2 x float> %X.coerce0, float %X.coerce1)
218 return X.c;
219 }
220
f32(_Complex float A,_Complex float B)221 _Complex float f32(_Complex float A, _Complex float B) {
222 // rdar://6379669
223 // CHECK: define <2 x float> @f32(<2 x float> %A.coerce, <2 x float> %B.coerce)
224 return A+B;
225 }
226
227
228 // rdar://8357396
229 struct f33s { long x; float c,d; };
230
f33(va_list X)231 void f33(va_list X) {
232 va_arg(X, struct f33s);
233 }
234
235 typedef unsigned long long v1i64 __attribute__((__vector_size__(8)));
236
237 // rdar://8359248
238 // CHECK: define i64 @f34(i64 %arg.coerce)
f34(v1i64 arg)239 v1i64 f34(v1i64 arg) { return arg; }
240
241
242 // rdar://8358475
243 // CHECK: define i64 @f35(i64 %arg.coerce)
244 typedef unsigned long v1i64_2 __attribute__((__vector_size__(8)));
f35(v1i64_2 arg)245 v1i64_2 f35(v1i64_2 arg) { return arg+arg; }
246
247 // rdar://9122143
248 // CHECK: declare void @func(%struct._str* byval align 16)
249 typedef struct _str {
250 union {
251 long double a;
252 long c;
253 };
254 } str;
255
256 void func(str s);
257 str ss;
f9122143()258 void f9122143()
259 {
260 func(ss);
261 }
262
263 // CHECK: define double @f36(double %arg.coerce)
264 typedef unsigned v2i32 __attribute((__vector_size__(8)));
f36(v2i32 arg)265 v2i32 f36(v2i32 arg) { return arg; }
266
267 // AVX: declare void @f38(<8 x float>)
268 // AVX: declare void @f37(<8 x float>)
269 // CHECK: declare void @f38(%struct.s256* byval align 32)
270 // CHECK: declare void @f37(<8 x float>* byval align 32)
271 typedef float __m256 __attribute__ ((__vector_size__ (32)));
272 typedef struct {
273 __m256 m;
274 } s256;
275
276 s256 x38;
277 __m256 x37;
278
279 void f38(s256 x);
280 void f37(__m256 x);
f39()281 void f39() { f38(x38); f37(x37); }
282
283 // The two next tests make sure that the struct below is passed
284 // in the same way regardless of avx being used
285
286 // CHECK: declare void @func40(%struct.t128* byval align 16)
287 typedef float __m128 __attribute__ ((__vector_size__ (16)));
288 typedef struct t128 {
289 __m128 m;
290 __m128 n;
291 } two128;
292
293 extern void func40(two128 s);
func41(two128 s)294 void func41(two128 s) {
295 func40(s);
296 }
297
298 // CHECK: declare void @func42(%struct.t128_2* byval align 16)
299 typedef struct xxx {
300 __m128 array[2];
301 } Atwo128;
302 typedef struct t128_2 {
303 Atwo128 x;
304 } SA;
305
306 extern void func42(SA s);
func43(SA s)307 void func43(SA s) {
308 func42(s);
309 }
310
311 // CHECK: define i32 @f44
312 // CHECK: ptrtoint
313 // CHECK-NEXT: and {{.*}}, -32
314 // CHECK-NEXT: inttoptr
315 typedef int T44 __attribute((vector_size(32)));
316 struct s44 { T44 x; int y; };
f44(int i,...)317 int f44(int i, ...) {
318 __builtin_va_list ap;
319 __builtin_va_start(ap, i);
320 struct s44 s = __builtin_va_arg(ap, struct s44);
321 __builtin_va_end(ap);
322 return s.y;
323 }
324
325 // Text that vec3 returns the correct LLVM IR type.
326 // AVX: define i32 @foo(<3 x i64> %X)
327 typedef long long3 __attribute((ext_vector_type(3)));
foo(long3 X)328 int foo(long3 X)
329 {
330 return 0;
331 }
332
333 // Make sure we don't use a varargs convention for a function without a
334 // prototype where AVX types are involved.
335 // AVX: @test45
336 // AVX: call i32 bitcast (i32 (...)* @f45 to i32 (<8 x float>)*)
337 int f45();
338 __m256 x45;
test45()339 void test45() { f45(x45); }
340
341 // Make sure we use byval to pass 64-bit vectors in memory; the LLVM call
342 // lowering can't handle this case correctly because it runs after legalization.
343 // CHECK: @test46
344 // CHECK: call void @f46({{.*}}<2 x float>* byval align 8 {{.*}}, <2 x float>* byval align 8 {{.*}})
345 typedef float v46 __attribute((vector_size(8)));
346 void f46(v46,v46,v46,v46,v46,v46,v46,v46,v46,v46);
test46()347 void test46() { v46 x = {1,2}; f46(x,x,x,x,x,x,x,x,x,x); }
348
349 // Check that we pass the struct below without using byval, which helps out
350 // codegen.
351 //
352 // CHECK: @test47
353 // CHECK: call void @f47(i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}})
354 struct s47 { unsigned a; };
355 void f47(int,int,int,int,int,int,struct s47);
test47(int a,struct s47 b)356 void test47(int a, struct s47 b) { f47(a, a, a, a, a, a, b); }
357