1 // REQUIRES: arm-registered-target
2 // RUN: %clang_cc1 -triple armv7---eabi -target-abi aapcs -mfloat-abi hard -emit-llvm %s -o - | FileCheck %s
4 // RUN: %clang_cc1 -triple arm64-apple-darwin9 -target-abi darwinpcs \
5 // RUN: -ffreestanding -emit-llvm -w -o - %s | FileCheck -check-prefix=CHECK64 %s
7 // RUN: %clang_cc1 -triple arm64-linux-gnu -ffreestanding -emit-llvm -w -o - %s \
8 // RUN: | FileCheck --check-prefix=CHECK64 %s
9 typedef long long int64_t;
10 typedef unsigned int uint32_t;
12 /* This is not a homogenous aggregate - fundamental types are different */
16 } union_with_first_floats
;
17 union_with_first_floats g_u_f
;
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);
22 void test_union_with_first_floats(void) {
23 takes_union_with_first_floats(g_u_f
);
25 // CHECK: declare arm_aapcs_vfpcc void @takes_union_with_first_floats([4 x i32])
27 void test_return_union_with_first_floats(void) {
28 g_u_f
= returns_union_with_first_floats();
30 // CHECK: declare arm_aapcs_vfpcc void @returns_union_with_first_floats(ptr dead_on_unwind writable sret(%union.union_with_first_floats) align 4)
32 /* This is not a homogenous aggregate - fundamental types are different */
36 } union_with_non_first_floats
;
37 union_with_non_first_floats g_u_nf_f
;
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);
42 void test_union_with_non_first_floats(void) {
43 takes_union_with_non_first_floats(g_u_nf_f
);
45 // CHECK: declare arm_aapcs_vfpcc void @takes_union_with_non_first_floats([4 x i32])
47 void test_return_union_with_non_first_floats(void) {
48 g_u_nf_f
= returns_union_with_non_first_floats();
50 // CHECK: declare arm_aapcs_vfpcc void @returns_union_with_non_first_floats(ptr dead_on_unwind writable sret(%union.union_with_non_first_floats) align 4)
52 /* This is not a homogenous aggregate - fundamental types are different */
55 union_with_first_floats b
;
56 } struct_with_union_with_first_floats
;
57 struct_with_union_with_first_floats g_s_f
;
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);
62 void test_struct_with_union_with_first_floats(void) {
63 takes_struct_with_union_with_first_floats(g_s_f
);
65 // CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_union_with_first_floats([5 x i32])
67 void test_return_struct_with_union_with_first_floats(void) {
68 g_s_f
= returns_struct_with_union_with_first_floats();
70 // CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_first_floats(ptr dead_on_unwind writable sret(%struct.struct_with_union_with_first_floats) align 4)
72 /* This is not a homogenous aggregate - fundamental types are different */
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
;
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);
82 void test_struct_with_union_with_non_first_floats(void) {
83 takes_struct_with_union_with_non_first_floats(g_s_nf_f
);
85 // CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_union_with_non_first_floats([5 x i32])
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();
90 // CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_non_first_floats(ptr dead_on_unwind writable sret(%struct.struct_with_union_with_non_first_floats) align 4)
92 /* Plain array is not a homogenous aggregate */
93 extern void takes_array_of_floats(float a
[4]);
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
);
98 // CHECK: declare arm_aapcs_vfpcc void @takes_array_of_floats(ptr noundef)
100 /* Struct-type homogenous aggregate */
103 } struct_with_fundamental_elems
;
104 struct_with_fundamental_elems g_s
;
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);
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 {{.*}})
113 // CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_fundamental_elems(%struct.struct_with_fundamental_elems)
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()
119 // CHECK: declare arm_aapcs_vfpcc %struct.struct_with_fundamental_elems @returns_struct_with_fundamental_elems()
121 /* Array-type homogenous aggregate */
125 struct_with_array g_s_a
;
127 extern void takes_struct_with_array(struct_with_array a
);
128 extern struct_with_array
returns_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 {{.*}})
134 // CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_array(%struct.struct_with_array)
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()
140 // CHECK: declare arm_aapcs_vfpcc %struct.struct_with_array @returns_struct_with_array()
142 /* This union is a homogenous aggregate. Check that it's passed properly */
144 struct_with_fundamental_elems xyzw
;
146 } union_with_struct_with_fundamental_elems
;
147 union_with_struct_with_fundamental_elems g_u_s_fe
;
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);
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 {{.*}})
156 // CHECK: declare arm_aapcs_vfpcc void @takes_union_with_struct_with_fundamental_elems(%union.union_with_struct_with_fundamental_elems)
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()
162 // CHECK: declare arm_aapcs_vfpcc %union.union_with_struct_with_fundamental_elems @returns_union_with_struct_with_fundamental_elems()
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.
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
;
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 {{.*}}, [4 x double] {{.*}}, [4 x double] {{.*}}, double {{.*}})
180 takes_struct_of_four_doubles(3.0, g_s4d
, g_s4d
, 4.0);
183 extern void takes_struct_of_four_doubles_variadic(double a
, struct_of_four_doubles b
, struct_of_four_doubles c
, double d
, ...);
185 void test_struct_of_four_doubles_variadic(void) {
186 // CHECK: test_struct_of_four_doubles_variadic
187 // 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 takes_struct_of_four_doubles_variadic(3.0, g_s4d
, g_s4d
, 4.0);
191 extern void takes_struct_with_backfill(float f1
, double a
, float f2
, struct_of_four_doubles b
, struct_of_four_doubles c
, double d
);
192 void test_struct_with_backfill(void) {
193 // CHECK: test_struct_with_backfill
194 // CHECK: call arm_aapcs_vfpcc void @takes_struct_with_backfill(float {{.*}}, double {{.*}}, float {{.*}}, %struct.struct_of_four_doubles {{.*}}, %struct.struct_of_four_doubles {{.*}}, double {{.*}})
195 takes_struct_with_backfill(3.0, 3.1, 3.2, g_s4d
, g_s4d
, 4.0);
198 typedef __attribute__(( ext_vector_type(8) )) char __char8
;
199 typedef __attribute__(( ext_vector_type(4) )) short __short4
;
206 extern void takes_struct_of_vecs(double a
, struct_of_vecs b
, struct_of_vecs c
, double d
);
207 struct_of_vecs g_vec
;
209 void test_struct_of_vecs(void) {
210 // CHECK: test_struct_of_vecs
211 // CHECK: call arm_aapcs_vfpcc void @takes_struct_of_vecs(double {{.*}}, %struct.struct_of_vecs {{.*}}, %struct.struct_of_vecs {{.*}}, double {{.*}})
212 // CHECK64: test_struct_of_vecs
213 // CHECK64: call void @takes_struct_of_vecs(double {{.*}}, [4 x <8 x i8>] {{.*}}, [4 x <8 x i8>] {{.*}}, double {{.*}})
214 takes_struct_of_vecs(3.0, g_vec
, g_vec
, 4.0);
220 } struct_of_double_and_long_double
;
221 struct_of_double_and_long_double g_dld
;
223 struct_of_double_and_long_double
test_struct_of_double_and_long_double(void) {
226 // CHECK: define{{.*}} arm_aapcs_vfpcc %struct.struct_of_double_and_long_double @test_struct_of_double_and_long_double()
228 // FIXME: Tests necessary: