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