x86_64-arguments.c revision a8b7a7d3eaa51dd200cba1e5541f2542d24d7a6e
1// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s| FileCheck %s
2#include <stdarg.h>
3
4// CHECK: %0 = type { i64, double }
5
6// CHECK: define signext i8 @f0()
7char f0(void) {
8  return 0;
9}
10
11// CHECK: define signext i16 @f1()
12short f1(void) {
13  return 0;
14}
15
16// CHECK: define i32 @f2()
17int f2(void) {
18  return 0;
19}
20
21// CHECK: define float @f3()
22float f3(void) {
23  return 0;
24}
25
26// CHECK: define double @f4()
27double f4(void) {
28  return 0;
29}
30
31// CHECK: define x86_fp80 @f5()
32long double f5(void) {
33  return 0;
34}
35
36// CHECK: define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8* %a4)
37void f6(char a0, short a1, int a2, long long a3, void *a4) {
38}
39
40// CHECK: define void @f7(i32 %a0)
41typedef enum { A, B, C } e7;
42void f7(e7 a0) {
43}
44
45// Test merging/passing of upper eightbyte with X87 class.
46//
47// CHECK: define %0 @f8_1()
48// CHECK: define void @f8_2(i64 %a0.coerce0, double %a0.coerce1)
49union u8 {
50  long double a;
51  int b;
52};
53union u8 f8_1() { while (1) {} }
54void f8_2(union u8 a0) {}
55
56// CHECK: define i64 @f9()
57struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} }
58
59// CHECK: define void @f10(i64 %a0.coerce)
60struct s10 { int a; int b; int : 0; };
61void f10(struct s10 a0) {}
62
63// CHECK: define void @f11(%struct.s19* sret %agg.result)
64union { long double a; float b; } f11() { while (1) {} }
65
66// CHECK: define i32 @f12_0()
67// CHECK: define void @f12_1(i32 %a0.coerce)
68struct s12 { int a __attribute__((aligned(16))); };
69struct s12 f12_0(void) { while (1) {} }
70void f12_1(struct s12 a0) {}
71
72// Check that sret parameter is accounted for when checking available integer
73// registers.
74// CHECK: define void @f13(%struct.s13_0* sret %agg.result, i32 %a, i32 %b, i32 %c, i32 %d, {{.*}}* byval %e, i32 %f)
75
76struct s13_0 { long long f0[3]; };
77struct s13_1 { long long f0[2]; };
78struct s13_0 f13(int a, int b, int c, int d,
79                 struct s13_1 e, int f) { while (1) {} }
80
81// CHECK: define void @f14({{.*}}, i8 signext %X)
82void f14(int a, int b, int c, int d, int e, int f, char X) {}
83
84// CHECK: define void @f15({{.*}}, i8* %X)
85void f15(int a, int b, int c, int d, int e, int f, void *X) {}
86
87// CHECK: define void @f16({{.*}}, float %X)
88void f16(float a, float b, float c, float d, float e, float f, float g, float h,
89         float X) {}
90
91// CHECK: define void @f17({{.*}}, x86_fp80 %X)
92void f17(float a, float b, float c, float d, float e, float f, float g, float h,
93         long double X) {}
94
95// Check for valid coercion.  The struct should be passed/returned as i32, not
96// as i64 for better code quality.
97// rdar://8135035
98// CHECK: define void @f18(i32 %a, i32 %f18_arg1.coerce)
99struct f18_s0 { int f0; };
100void f18(int a, struct f18_s0 f18_arg1) { while (1) {} }
101
102// Check byval alignment.
103
104// CHECK: define void @f19(%struct.s19* byval align 16 %x)
105struct s19 {
106  long double a;
107};
108void f19(struct s19 x) {}
109
110// CHECK: define void @f20(%struct.s20* byval align 32 %x)
111struct __attribute__((aligned(32))) s20 {
112  int x;
113  int y;
114};
115void f20(struct s20 x) {}
116
117struct StringRef {
118  long x;
119  const char *Ptr;
120};
121
122// rdar://7375902
123// CHECK: define i8* @f21(i64 %S.coerce0, i8* %S.coerce1)
124const char *f21(struct StringRef S) { return S.x+S.Ptr; }
125
126// PR7567
127typedef __attribute__ ((aligned(16))) struct f22s { unsigned long long x[2]; } L;
128void f22(L x, L y) { }
129// CHECK: @f22
130// CHECK: %x = alloca{{.*}}, align 16
131// CHECK: %y = alloca{{.*}}, align 16
132
133
134
135// PR7714
136struct f23S {
137  short f0;
138  unsigned f1;
139  int f2;
140};
141
142
143void f23(int A, struct f23S B) {
144  // CHECK: define void @f23(i32 %A, i64 %B.coerce0, i32 %B.coerce1)
145}
146
147struct f24s { long a; int b; };
148
149struct f23S f24(struct f23S *X, struct f24s *P2) {
150  return *X;
151
152  // CHECK: define %struct.f24s @f24(%struct.f23S* %X, %struct.f24s* %P2)
153}
154
155// rdar://8248065
156typedef float v4f32 __attribute__((__vector_size__(16)));
157v4f32 f25(v4f32 X) {
158  // CHECK: define <4 x float> @f25(<4 x float> %X)
159  // CHECK-NOT: alloca
160  // CHECK: alloca <4 x float>
161  // CHECK-NOT: alloca
162  // CHECK: store <4 x float> %X, <4 x float>*
163  // CHECK-NOT: store
164  // CHECK: ret <4 x float>
165  return X+X;
166}
167
168struct foo26 {
169  int *X;
170  float *Y;
171};
172
173struct foo26 f26(struct foo26 *P) {
174  // CHECK: define %struct.foo26 @f26(%struct.foo26* %P)
175  return *P;
176}
177
178
179struct v4f32wrapper {
180  v4f32 v;
181};
182
183struct v4f32wrapper f27(struct v4f32wrapper X) {
184  // CHECK: define <4 x float> @f27(<4 x float> %X.coerce)
185  return X;
186}
187
188// rdar://5711709
189struct f28c {
190  double x;
191  int y;
192};
193void f28(struct f28c C) {
194  // CHECK: define void @f28(double %C.coerce0, i32 %C.coerce1)
195}
196
197struct f29a {
198  struct c {
199    double x;
200    int y;
201  } x[1];
202};
203
204void f29a(struct f29a A) {
205  // CHECK: define void @f29a(double %A.coerce0, i32 %A.coerce1)
206}
207
208// rdar://8249586
209struct S0 { char f0[8]; char f2; char f3; char f4; };
210void f30(struct S0 p_4) {
211  // CHECK: define void @f30(i64 %p_4.coerce0, i24 %p_4.coerce1)
212}
213
214// Pass the third element as a float when followed by tail padding.
215// rdar://8251384
216struct f31foo { float a, b, c; };
217float f31(struct f31foo X) {
218  // CHECK: define float @f31(<2 x float> %X.coerce0, float %X.coerce1)
219  return X.c;
220}
221
222_Complex float f32(_Complex float A, _Complex float B) {
223  // rdar://6379669
224  // CHECK: define <2 x float> @f32(<2 x float> %A.coerce, <2 x float> %B.coerce)
225  return A+B;
226}
227
228
229// rdar://8357396
230struct f33s { long x; float c,d; };
231
232void f33(va_list X) {
233  va_arg(X, struct f33s);
234}
235
236
237