• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // REQUIRES: arm-registered-target
2 // RUN: %clang_cc1 -triple armv7---eabi -target-abi aapcs -mfloat-abi hard -emit-llvm %s -o - | FileCheck %s
3 
4 // RUN: %clang_cc1 -triple arm64-apple-darwin9 -target-abi darwinpcs \
5 // RUN:  -ffreestanding -emit-llvm -w -o - %s | FileCheck -check-prefix=CHECK64 %s
6 
7 // RUN: %clang_cc1 -triple arm64-linux-gnu -ffreestanding -emit-llvm -w -o - %s \
8 // RUN:   | FileCheck --check-prefix=CHECK64-AAPCS %s
9 typedef long long int64_t;
10 typedef unsigned int uint32_t;
11 
12 /* This is not a homogenous aggregate - fundamental types are different */
13 typedef union {
14   float       f[4];
15   uint32_t    i[4];
16 } union_with_first_floats;
17 union_with_first_floats g_u_f;
18 
19 extern void takes_union_with_first_floats(union_with_first_floats a);
20 extern union_with_first_floats returns_union_with_first_floats(void);
21 
test_union_with_first_floats(void)22 void test_union_with_first_floats(void) {
23   takes_union_with_first_floats(g_u_f);
24 }
25 // CHECK: declare arm_aapcs_vfpcc void @takes_union_with_first_floats({ [4 x i32] })
26 
test_return_union_with_first_floats(void)27 void test_return_union_with_first_floats(void) {
28   g_u_f = returns_union_with_first_floats();
29 }
30 // CHECK: declare arm_aapcs_vfpcc void @returns_union_with_first_floats(%union.union_with_first_floats* sret)
31 
32 /* This is not a homogenous aggregate - fundamental types are different */
33 typedef union {
34     uint32_t    i[4];
35     float       f[4];
36 } union_with_non_first_floats;
37 union_with_non_first_floats g_u_nf_f;
38 
39 extern void takes_union_with_non_first_floats(union_with_non_first_floats a);
40 extern union_with_non_first_floats returns_union_with_non_first_floats(void);
41 
test_union_with_non_first_floats(void)42 void test_union_with_non_first_floats(void) {
43   takes_union_with_non_first_floats(g_u_nf_f);
44 }
45 // CHECK: declare arm_aapcs_vfpcc void @takes_union_with_non_first_floats({ [4 x i32] })
46 
test_return_union_with_non_first_floats(void)47 void test_return_union_with_non_first_floats(void) {
48   g_u_nf_f = returns_union_with_non_first_floats();
49 }
50 // CHECK: declare arm_aapcs_vfpcc void @returns_union_with_non_first_floats(%union.union_with_non_first_floats* sret)
51 
52 /* This is not a homogenous aggregate - fundamental types are different */
53 typedef struct {
54   float a;
55   union_with_first_floats b;
56 } struct_with_union_with_first_floats;
57 struct_with_union_with_first_floats g_s_f;
58 
59 extern void takes_struct_with_union_with_first_floats(struct_with_union_with_first_floats a);
60 extern struct_with_union_with_first_floats returns_struct_with_union_with_first_floats(void);
61 
test_struct_with_union_with_first_floats(void)62 void test_struct_with_union_with_first_floats(void) {
63   takes_struct_with_union_with_first_floats(g_s_f);
64 }
65 // CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_union_with_first_floats({ [5 x i32] })
66 
test_return_struct_with_union_with_first_floats(void)67 void test_return_struct_with_union_with_first_floats(void) {
68   g_s_f = returns_struct_with_union_with_first_floats();
69 }
70 // CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_first_floats(%struct.struct_with_union_with_first_floats* sret)
71 
72 /* This is not a homogenous aggregate - fundamental types are different */
73 typedef struct {
74   float a;
75   union_with_non_first_floats b;
76 } struct_with_union_with_non_first_floats;
77 struct_with_union_with_non_first_floats g_s_nf_f;
78 
79 extern void takes_struct_with_union_with_non_first_floats(struct_with_union_with_non_first_floats a);
80 extern struct_with_union_with_non_first_floats returns_struct_with_union_with_non_first_floats(void);
81 
test_struct_with_union_with_non_first_floats(void)82 void test_struct_with_union_with_non_first_floats(void) {
83   takes_struct_with_union_with_non_first_floats(g_s_nf_f);
84 }
85 // CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_union_with_non_first_floats({ [5 x i32] })
86 
test_return_struct_with_union_with_non_first_floats(void)87 void test_return_struct_with_union_with_non_first_floats(void) {
88   g_s_nf_f = returns_struct_with_union_with_non_first_floats();
89 }
90 // CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_non_first_floats(%struct.struct_with_union_with_non_first_floats* sret)
91 
92 /* Plain array is not a homogenous aggregate */
93 extern void takes_array_of_floats(float a[4]);
test_array_of_floats(void)94 void test_array_of_floats(void) {
95   float a[4] = {1.0, 2.0, 3.0, 4.0};
96   takes_array_of_floats(a);
97 }
98 // CHECK: declare arm_aapcs_vfpcc void @takes_array_of_floats(float*)
99 
100 /* Struct-type homogenous aggregate */
101 typedef struct {
102   float x, y, z, w;
103 } struct_with_fundamental_elems;
104 struct_with_fundamental_elems g_s;
105 
106 extern void takes_struct_with_fundamental_elems(struct_with_fundamental_elems a);
107 extern struct_with_fundamental_elems returns_struct_with_fundamental_elems(void);
108 
test_struct_with_fundamental_elems(void)109 void test_struct_with_fundamental_elems(void) {
110   takes_struct_with_fundamental_elems(g_s);
111 // CHECK:  call arm_aapcs_vfpcc  void @takes_struct_with_fundamental_elems(%struct.struct_with_fundamental_elems {{.*}})
112 }
113 // CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_fundamental_elems(%struct.struct_with_fundamental_elems)
114 
test_return_struct_with_fundamental_elems(void)115 void test_return_struct_with_fundamental_elems(void) {
116   g_s = returns_struct_with_fundamental_elems();
117 // CHECK: call arm_aapcs_vfpcc  %struct.struct_with_fundamental_elems @returns_struct_with_fundamental_elems()
118 }
119 // CHECK: declare arm_aapcs_vfpcc %struct.struct_with_fundamental_elems @returns_struct_with_fundamental_elems()
120 
121 /* Array-type homogenous aggregate */
122 typedef struct {
123   float xyzw[4];
124 } struct_with_array;
125 struct_with_array g_s_a;
126 
127 extern void takes_struct_with_array(struct_with_array a);
128 extern struct_with_array returns_struct_with_array(void);
129 
test_struct_with_array(void)130 void test_struct_with_array(void) {
131   takes_struct_with_array(g_s_a);
132 // CHECK:   call arm_aapcs_vfpcc  void @takes_struct_with_array(%struct.struct_with_array {{.*}})
133 }
134 // CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_array(%struct.struct_with_array)
135 
test_return_struct_with_array(void)136 void test_return_struct_with_array(void) {
137   g_s_a = returns_struct_with_array();
138 // CHECK:   call arm_aapcs_vfpcc  %struct.struct_with_array @returns_struct_with_array()
139 }
140 // CHECK: declare arm_aapcs_vfpcc %struct.struct_with_array @returns_struct_with_array()
141 
142 /* This union is a homogenous aggregate. Check that it's passed properly */
143 typedef union {
144   struct_with_fundamental_elems xyzw;
145   float a[3];
146 } union_with_struct_with_fundamental_elems;
147 union_with_struct_with_fundamental_elems g_u_s_fe;
148 
149 extern void takes_union_with_struct_with_fundamental_elems(union_with_struct_with_fundamental_elems a);
150 extern union_with_struct_with_fundamental_elems returns_union_with_struct_with_fundamental_elems(void);
151 
test_union_with_struct_with_fundamental_elems(void)152 void test_union_with_struct_with_fundamental_elems(void) {
153   takes_union_with_struct_with_fundamental_elems(g_u_s_fe);
154 // CHECK: call arm_aapcs_vfpcc  void @takes_union_with_struct_with_fundamental_elems(%union.union_with_struct_with_fundamental_elems {{.*}})
155 }
156 // CHECK: declare arm_aapcs_vfpcc void @takes_union_with_struct_with_fundamental_elems(%union.union_with_struct_with_fundamental_elems)
157 
test_return_union_with_struct_with_fundamental_elems(void)158 void test_return_union_with_struct_with_fundamental_elems(void) {
159   g_u_s_fe = returns_union_with_struct_with_fundamental_elems();
160 // CHECK: call arm_aapcs_vfpcc  %union.union_with_struct_with_fundamental_elems @returns_union_with_struct_with_fundamental_elems()
161 }
162 // CHECK: declare arm_aapcs_vfpcc %union.union_with_struct_with_fundamental_elems @returns_union_with_struct_with_fundamental_elems()
163 
164 // Make sure HAs that can be partially fit into VFP registers will be allocated
165 // on stack and that later VFP candidates will go on stack as well.
166 typedef struct {
167   double x;
168   double a2;
169   double a3;
170   double a4;
171 } struct_of_four_doubles;
172 extern void takes_struct_of_four_doubles(double a, struct_of_four_doubles b, struct_of_four_doubles c, double d);
173 struct_of_four_doubles g_s4d;
174 
test_struct_of_four_doubles(void)175 void test_struct_of_four_doubles(void) {
176 // CHECK: test_struct_of_four_doubles
177 // CHECK: call arm_aapcs_vfpcc void @takes_struct_of_four_doubles(double {{.*}}, %struct.struct_of_four_doubles {{.*}}, %struct.struct_of_four_doubles {{.*}}, double {{.*}})
178 // CHECK64: test_struct_of_four_doubles
179 // CHECK64: call void @takes_struct_of_four_doubles(double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, [3 x float] undef, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}})
180 // CHECK64-AAPCS: test_struct_of_four_doubles
181 // CHECK64-AAPCS: call void @takes_struct_of_four_doubles(double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, [3 x float] undef, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}})
182   takes_struct_of_four_doubles(3.0, g_s4d, g_s4d, 4.0);
183 }
184 
185 extern void takes_struct_of_four_doubles_variadic(double a, struct_of_four_doubles b, struct_of_four_doubles c, double d, ...);
186 
test_struct_of_four_doubles_variadic(void)187 void test_struct_of_four_doubles_variadic(void) {
188 // CHECK: test_struct_of_four_doubles_variadic
189 // CHECK: call arm_aapcs_vfpcc void (double, { [4 x i64] }, { [4 x i64] }, double, ...)* @takes_struct_of_four_doubles_variadic(double {{.*}}, { [4 x i64] } {{.*}}, { [4 x i64] } {{.*}}, double {{.*}})
190   takes_struct_of_four_doubles_variadic(3.0, g_s4d, g_s4d, 4.0);
191 }
192 
193 extern void takes_struct_with_backfill(float f1, double a, float f2, struct_of_four_doubles b, struct_of_four_doubles c, double d);
test_struct_with_backfill(void)194 void test_struct_with_backfill(void) {
195 // CHECK: test_struct_with_backfill
196 // CHECK: call arm_aapcs_vfpcc void @takes_struct_with_backfill(float {{.*}}, double {{.*}}, float {{.*}}, %struct.struct_of_four_doubles {{.*}}, %struct.struct_of_four_doubles {{.*}}, double {{.*}})
197   takes_struct_with_backfill(3.0, 3.1, 3.2, g_s4d, g_s4d, 4.0);
198 }
199 
200 typedef __attribute__(( ext_vector_type(8) )) char __char8;
201 typedef __attribute__(( ext_vector_type(4) ))  short __short4;
202 typedef struct {
203   __char8  a1;
204   __short4 a2;
205   __char8  a3;
206   __short4 a4;
207 } struct_of_vecs;
208 extern void takes_struct_of_vecs(double a, struct_of_vecs b, struct_of_vecs c, double d);
209 struct_of_vecs g_vec;
210 
test_struct_of_vecs(void)211 void test_struct_of_vecs(void) {
212 // CHECK: test_struct_of_vecs
213 // CHECK: call arm_aapcs_vfpcc void @takes_struct_of_vecs(double {{.*}}, %struct.struct_of_vecs {{.*}}, %struct.struct_of_vecs {{.*}}, double {{.*}})
214 // CHECK64: test_struct_of_vecs
215 // CHECK64: call void @takes_struct_of_vecs(double {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, [3 x float] undef, <8 x i8> {{.*}}, <4 x i16> {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, double {{.*}})
216 // CHECK64-AAPCS: test_struct_of_vecs
217 // CHECK64-AAPCS: call void @takes_struct_of_vecs(double {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, [3 x float] undef, <8 x i8> {{.*}}, <4 x i16> {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, double {{.*}})
218   takes_struct_of_vecs(3.0, g_vec, g_vec, 4.0);
219 }
220 
221 typedef struct {
222   double a;
223   long double b;
224 } struct_of_double_and_long_double;
225 struct_of_double_and_long_double g_dld;
226 
test_struct_of_double_and_long_double(void)227 struct_of_double_and_long_double test_struct_of_double_and_long_double(void) {
228   return g_dld;
229 }
230 // CHECK: define arm_aapcs_vfpcc %struct.struct_of_double_and_long_double @test_struct_of_double_and_long_double()
231 
232 // FIXME: Tests necessary:
233 //         - Vectors
234 //         - C++ stuff
235