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