x86_64-arguments.c revision 9c254f0415bef9a0bafe5b5026ddb54b727597b1
1// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o %t %s
2// RUN: FileCheck < %t %s
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 i64 @f12_0()
67// CHECK: define void @f12_1(i64 %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, %struct.s13_1* 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