• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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