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