blob: d7a42822c5a808e469eb2ebb08d3722dd91d9841 [file] [log] [blame]
Chris Lattner22fd4ba2010-08-25 23:39:14 +00001// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s| FileCheck %s
Chris Lattnera8b7a7d2010-08-26 06:28:35 +00002#include <stdarg.h>
Daniel Dunbar644f4c32009-02-14 02:09:24 +00003
Daniel Dunbar0aa1cba2010-04-21 19:10:54 +00004// CHECK: define signext i8 @f0()
Daniel Dunbar644f4c32009-02-14 02:09:24 +00005char f0(void) {
Mike Stumpc36541e2009-07-21 20:52:43 +00006 return 0;
Daniel Dunbar644f4c32009-02-14 02:09:24 +00007}
8
Daniel Dunbar0aa1cba2010-04-21 19:10:54 +00009// CHECK: define signext i16 @f1()
Daniel Dunbar644f4c32009-02-14 02:09:24 +000010short f1(void) {
Mike Stumpc36541e2009-07-21 20:52:43 +000011 return 0;
Daniel Dunbar644f4c32009-02-14 02:09:24 +000012}
13
Daniel Dunbar0aa1cba2010-04-21 19:10:54 +000014// CHECK: define i32 @f2()
Daniel Dunbar644f4c32009-02-14 02:09:24 +000015int f2(void) {
Mike Stumpc36541e2009-07-21 20:52:43 +000016 return 0;
Daniel Dunbar644f4c32009-02-14 02:09:24 +000017}
18
Daniel Dunbar0aa1cba2010-04-21 19:10:54 +000019// CHECK: define float @f3()
Daniel Dunbar644f4c32009-02-14 02:09:24 +000020float f3(void) {
Mike Stumpc36541e2009-07-21 20:52:43 +000021 return 0;
Daniel Dunbar644f4c32009-02-14 02:09:24 +000022}
23
Daniel Dunbar0aa1cba2010-04-21 19:10:54 +000024// CHECK: define double @f4()
Daniel Dunbar644f4c32009-02-14 02:09:24 +000025double f4(void) {
Mike Stumpc36541e2009-07-21 20:52:43 +000026 return 0;
Daniel Dunbar644f4c32009-02-14 02:09:24 +000027}
28
Daniel Dunbar0aa1cba2010-04-21 19:10:54 +000029// CHECK: define x86_fp80 @f5()
Daniel Dunbar644f4c32009-02-14 02:09:24 +000030long double f5(void) {
Mike Stumpc36541e2009-07-21 20:52:43 +000031 return 0;
Daniel Dunbar644f4c32009-02-14 02:09:24 +000032}
33
Daniel Dunbar0aa1cba2010-04-21 19:10:54 +000034// CHECK: define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8* %a4)
Daniel Dunbar644f4c32009-02-14 02:09:24 +000035void f6(char a0, short a1, int a2, long long a3, void *a4) {
36}
Anders Carlsson730f9092009-02-26 17:38:19 +000037
Daniel Dunbar0aa1cba2010-04-21 19:10:54 +000038// CHECK: define void @f7(i32 %a0)
39typedef enum { A, B, C } e7;
40void f7(e7 a0) {
Mike Stump4b871422009-02-26 19:00:14 +000041}
Daniel Dunbar100f4022009-03-06 17:50:25 +000042
43// Test merging/passing of upper eightbyte with X87 class.
Daniel Dunbar0aa1cba2010-04-21 19:10:54 +000044//
Chris Lattner9cbe4f02011-07-09 17:41:47 +000045// CHECK: define void @f8_1(%union.u8* sret %agg.result)
46// CHECK: define void @f8_2(%union.u8* byval align 16 %a0)
Daniel Dunbar100f4022009-03-06 17:50:25 +000047union u8 {
48 long double a;
49 int b;
50};
Mike Stumpc36541e2009-07-21 20:52:43 +000051union u8 f8_1() { while (1) {} }
Daniel Dunbar100f4022009-03-06 17:50:25 +000052void f8_2(union u8 a0) {}
Daniel Dunbar8236bf12009-05-08 22:26:44 +000053
Daniel Dunbar0aa1cba2010-04-21 19:10:54 +000054// CHECK: define i64 @f9()
Mike Stumpc36541e2009-07-21 20:52:43 +000055struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} }
Daniel Dunbar8236bf12009-05-08 22:26:44 +000056
Chris Lattner225e2862010-06-29 00:14:52 +000057// CHECK: define void @f10(i64 %a0.coerce)
Daniel Dunbar8236bf12009-05-08 22:26:44 +000058struct s10 { int a; int b; int : 0; };
59void f10(struct s10 a0) {}
60
Chris Lattner9cbe4f02011-07-09 17:41:47 +000061// CHECK: define void @f11(%"union.<anonymous>"* sret %agg.result)
Mike Stumpc36541e2009-07-21 20:52:43 +000062union { long double a; float b; } f11() { while (1) {} }
Daniel Dunbar20e95c52009-05-12 15:22:40 +000063
Chris Lattnere2962be2010-07-29 07:30:00 +000064// CHECK: define i32 @f12_0()
65// CHECK: define void @f12_1(i32 %a0.coerce)
Daniel Dunbar7ef455b2009-05-13 18:54:26 +000066struct s12 { int a __attribute__((aligned(16))); };
Mike Stumpc36541e2009-07-21 20:52:43 +000067struct s12 f12_0(void) { while (1) {} }
Daniel Dunbar7ef455b2009-05-13 18:54:26 +000068void f12_1(struct s12 a0) {}
69
Daniel Dunbar3a5f5c52009-05-22 17:33:44 +000070// Check that sret parameter is accounted for when checking available integer
71// registers.
Chris Lattner855d2272011-05-22 23:21:23 +000072// CHECK: define void @f13(%struct.s13_0* sret %agg.result, i32 %a, i32 %b, i32 %c, i32 %d, {{.*}}* byval align 8 %e, i32 %f)
Daniel Dunbar3a5f5c52009-05-22 17:33:44 +000073
74struct s13_0 { long long f0[3]; };
Daniel Dunbar55a759b2009-08-23 19:28:59 +000075struct s13_1 { long long f0[2]; };
Daniel Dunbar0aa1cba2010-04-21 19:10:54 +000076struct s13_0 f13(int a, int b, int c, int d,
Daniel Dunbar55a759b2009-08-23 19:28:59 +000077 struct s13_1 e, int f) { while (1) {} }
Daniel Dunbar3a5f5c52009-05-22 17:33:44 +000078
Daniel Dunbar0aa1cba2010-04-21 19:10:54 +000079// CHECK: define void @f14({{.*}}, i8 signext %X)
80void f14(int a, int b, int c, int d, int e, int f, char X) {}
81
82// CHECK: define void @f15({{.*}}, i8* %X)
83void f15(int a, int b, int c, int d, int e, int f, void *X) {}
84
85// CHECK: define void @f16({{.*}}, float %X)
Daniel Dunbar86e13ee2009-05-26 16:37:37 +000086void f16(float a, float b, float c, float d, float e, float f, float g, float h,
87 float X) {}
Daniel Dunbar0aa1cba2010-04-21 19:10:54 +000088
89// CHECK: define void @f17({{.*}}, x86_fp80 %X)
Daniel Dunbar86e13ee2009-05-26 16:37:37 +000090void f17(float a, float b, float c, float d, float e, float f, float g, float h,
91 long double X) {}
92
Chris Lattnerfaf23b72010-06-28 19:56:59 +000093// Check for valid coercion. The struct should be passed/returned as i32, not
94// as i64 for better code quality.
95// rdar://8135035
Chris Lattner225e2862010-06-29 00:14:52 +000096// CHECK: define void @f18(i32 %a, i32 %f18_arg1.coerce)
Daniel Dunbar55a759b2009-08-23 19:28:59 +000097struct f18_s0 { int f0; };
98void f18(int a, struct f18_s0 f18_arg1) { while (1) {} }
Daniel Dunbarfdf49862009-06-05 07:58:54 +000099
Daniel Dunbar46c54fb2010-04-21 19:49:55 +0000100// Check byval alignment.
101
102// CHECK: define void @f19(%struct.s19* byval align 16 %x)
103struct s19 {
104 long double a;
105};
106void f19(struct s19 x) {}
107
108// CHECK: define void @f20(%struct.s20* byval align 32 %x)
109struct __attribute__((aligned(32))) s20 {
110 int x;
111 int y;
112};
113void f20(struct s20 x) {}
Chris Lattner9c254f02010-06-29 06:01:59 +0000114
115struct StringRef {
116 long x;
117 const char *Ptr;
118};
119
120// rdar://7375902
121// CHECK: define i8* @f21(i64 %S.coerce0, i8* %S.coerce1)
122const char *f21(struct StringRef S) { return S.x+S.Ptr; }
123
Chris Lattner121b3fa2010-07-05 20:21:00 +0000124// PR7567
125typedef __attribute__ ((aligned(16))) struct f22s { unsigned long long x[2]; } L;
126void f22(L x, L y) { }
127// CHECK: @f22
128// CHECK: %x = alloca{{.*}}, align 16
129// CHECK: %y = alloca{{.*}}, align 16
130
131
Chris Lattner1daf8082010-07-28 22:15:08 +0000132
133// PR7714
134struct f23S {
135 short f0;
136 unsigned f1;
137 int f2;
138};
139
Chris Lattner519f68c2010-07-28 23:06:14 +0000140
Chris Lattner1daf8082010-07-28 22:15:08 +0000141void f23(int A, struct f23S B) {
142 // CHECK: define void @f23(i32 %A, i64 %B.coerce0, i32 %B.coerce1)
143}
144
Chris Lattner519f68c2010-07-28 23:06:14 +0000145struct f24s { long a; int b; };
Chris Lattner1daf8082010-07-28 22:15:08 +0000146
Chris Lattner519f68c2010-07-28 23:06:14 +0000147struct f23S f24(struct f23S *X, struct f24s *P2) {
148 return *X;
149
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000150 // CHECK: define { i64, i32 } @f24(%struct.f23S* %X, %struct.f24s* %P2)
Chris Lattner519f68c2010-07-28 23:06:14 +0000151}
Chris Lattner1daf8082010-07-28 22:15:08 +0000152
Chris Lattner800588f2010-07-29 06:26:06 +0000153// rdar://8248065
Chris Lattnerab5722e2010-07-28 23:47:21 +0000154typedef float v4f32 __attribute__((__vector_size__(16)));
Chris Lattnerab5722e2010-07-28 23:47:21 +0000155v4f32 f25(v4f32 X) {
Chris Lattner800588f2010-07-29 06:26:06 +0000156 // CHECK: define <4 x float> @f25(<4 x float> %X)
157 // CHECK-NOT: alloca
Chris Lattnerc10ab192010-07-29 17:14:05 +0000158 // CHECK: alloca <4 x float>
Chris Lattner800588f2010-07-29 06:26:06 +0000159 // CHECK-NOT: alloca
Chris Lattnerc10ab192010-07-29 17:14:05 +0000160 // CHECK: store <4 x float> %X, <4 x float>*
Chris Lattner800588f2010-07-29 06:26:06 +0000161 // CHECK-NOT: store
162 // CHECK: ret <4 x float>
Chris Lattnerab5722e2010-07-28 23:47:21 +0000163 return X+X;
164}
165
Chris Lattner4711cb02010-07-29 04:46:19 +0000166struct foo26 {
167 int *X;
168 float *Y;
169};
Chris Lattnerab5722e2010-07-28 23:47:21 +0000170
Chris Lattner4711cb02010-07-29 04:46:19 +0000171struct foo26 f26(struct foo26 *P) {
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000172 // CHECK: define { i32*, float* } @f26(%struct.foo26* %P)
Chris Lattner4711cb02010-07-29 04:46:19 +0000173 return *P;
174}
Chris Lattner15842bd2010-07-29 05:02:29 +0000175
176
177struct v4f32wrapper {
178 v4f32 v;
179};
180
181struct v4f32wrapper f27(struct v4f32wrapper X) {
182 // CHECK: define <4 x float> @f27(<4 x float> %X.coerce)
183 return X;
Chris Lattnere2962be2010-07-29 07:30:00 +0000184}
185
186// rdar://5711709
187struct f28c {
188 double x;
189 int y;
190};
191void f28(struct f28c C) {
192 // CHECK: define void @f28(double %C.coerce0, i32 %C.coerce1)
193}
194
Chris Lattner021c3a32010-07-29 07:43:55 +0000195struct f29a {
196 struct c {
197 double x;
198 int y;
199 } x[1];
200};
201
202void f29a(struct f29a A) {
203 // CHECK: define void @f29a(double %A.coerce0, i32 %A.coerce1)
204}
Chris Lattner9e45a3d2010-07-29 17:34:39 +0000205
206// rdar://8249586
207struct S0 { char f0[8]; char f2; char f3; char f4; };
208void f30(struct S0 p_4) {
209 // CHECK: define void @f30(i64 %p_4.coerce0, i24 %p_4.coerce1)
210}
Chris Lattnerf47c9442010-07-29 18:13:09 +0000211
212// Pass the third element as a float when followed by tail padding.
213// rdar://8251384
214struct f31foo { float a, b, c; };
215float f31(struct f31foo X) {
Chris Lattner22fd4ba2010-08-25 23:39:14 +0000216 // CHECK: define float @f31(<2 x float> %X.coerce0, float %X.coerce1)
Chris Lattnerf47c9442010-07-29 18:13:09 +0000217 return X.c;
218}
219
Chris Lattner22fd4ba2010-08-25 23:39:14 +0000220_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
Chris Lattnerf47c9442010-07-29 18:13:09 +0000226
Chris Lattnera8b7a7d2010-08-26 06:28:35 +0000227// rdar://8357396
228struct f33s { long x; float c,d; };
229
230void f33(va_list X) {
231 va_arg(X, struct f33s);
232}
233
Chris Lattner473f8e72010-08-26 18:03:20 +0000234typedef unsigned long long v1i64 __attribute__((__vector_size__(8)));
235
236// rdar://8359248
237// CHECK: define i64 @f34(i64 %arg.coerce)
238v1i64 f34(v1i64 arg) { return arg; }
Chris Lattnera8b7a7d2010-08-26 06:28:35 +0000239
Chris Lattner0fefa412010-08-26 18:13:50 +0000240
241// rdar://8358475
242// CHECK: define i64 @f35(i64 %arg.coerce)
243typedef unsigned long v1i64_2 __attribute__((__vector_size__(8)));
244v1i64_2 f35(v1i64_2 arg) { return arg+arg; }
245
John McCall67a57732011-04-21 01:20:55 +0000246// rdar://9122143
247// CHECK: declare void @func(%struct._str* byval align 16)
248typedef struct _str {
249 union {
250 long double a;
251 long c;
252 };
253} str;
254
255void func(str s);
256str ss;
257void f9122143()
258{
259 func(ss);
260}
261
Eli Friedman14508ff2011-07-02 00:57:27 +0000262// CHECK: define double @f36(double %arg.coerce)
263typedef unsigned v2i32 __attribute((__vector_size__(8)));
264v2i32 f36(v2i32 arg) { return arg; }