1 | // REQUIRES: arm-registered-target |
2 | // RUN: %clang_cc1 -triple armv7-apple-darwin9 -target-feature +neon -target-abi apcs-gnu -emit-llvm -w -o - %s | FileCheck -check-prefix=APCS-GNU %s |
3 | // RUN: %clang_cc1 -triple armv7-apple-darwin9 -target-feature +neon -target-abi aapcs -emit-llvm -w -o - %s | FileCheck -check-prefix=AAPCS %s |
4 | |
5 | // APCS-GNU-LABEL: define signext i8 @f0() |
6 | // AAPCS-LABEL: define arm_aapcscc signext i8 @f0() |
7 | char f0(void) { |
8 | return 0; |
9 | } |
10 | |
11 | // APCS-GNU-LABEL: define i8 @f1() |
12 | // AAPCS-LABEL: define arm_aapcscc i8 @f1() |
13 | struct s1 { char f0; }; |
14 | struct s1 f1(void) {} |
15 | |
16 | // APCS-GNU-LABEL: define i16 @f2() |
17 | // AAPCS-LABEL: define arm_aapcscc i16 @f2() |
18 | struct s2 { short f0; }; |
19 | struct s2 f2(void) {} |
20 | |
21 | // APCS-GNU-LABEL: define i32 @f3() |
22 | // AAPCS-LABEL: define arm_aapcscc i32 @f3() |
23 | struct s3 { int f0; }; |
24 | struct s3 f3(void) {} |
25 | |
26 | // APCS-GNU-LABEL: define i32 @f4() |
27 | // AAPCS-LABEL: define arm_aapcscc i32 @f4() |
28 | struct s4 { struct s4_0 { int f0; } f0; }; |
29 | struct s4 f4(void) {} |
30 | |
31 | // APCS-GNU-LABEL: define void @f5( |
32 | // APCS-GNU: struct.s5* noalias sret |
33 | // AAPCS-LABEL: define arm_aapcscc i32 @f5() |
34 | struct s5 { struct { } f0; int f1; }; |
35 | struct s5 f5(void) {} |
36 | |
37 | // APCS-GNU-LABEL: define void @f6( |
38 | // APCS-GNU: struct.s6* noalias sret |
39 | // AAPCS-LABEL: define arm_aapcscc i32 @f6() |
40 | struct s6 { int f0[1]; }; |
41 | struct s6 f6(void) {} |
42 | |
43 | // APCS-GNU-LABEL: define void @f7() |
44 | // AAPCS-LABEL: define arm_aapcscc void @f7() |
45 | struct s7 { struct { int : 0; } f0; }; |
46 | struct s7 f7(void) {} |
47 | |
48 | // APCS-GNU-LABEL: define void @f8( |
49 | // APCS-GNU: struct.s8* noalias sret |
50 | // AAPCS-LABEL: define arm_aapcscc void @f8() |
51 | struct s8 { struct { int : 0; } f0[1]; }; |
52 | struct s8 f8(void) {} |
53 | |
54 | // APCS-GNU-LABEL: define i32 @f9() |
55 | // AAPCS-LABEL: define arm_aapcscc i32 @f9() |
56 | struct s9 { int f0; int : 0; }; |
57 | struct s9 f9(void) {} |
58 | |
59 | // APCS-GNU-LABEL: define i32 @f10() |
60 | // AAPCS-LABEL: define arm_aapcscc i32 @f10() |
61 | struct s10 { int f0; int : 0; int : 0; }; |
62 | struct s10 f10(void) {} |
63 | |
64 | // APCS-GNU-LABEL: define void @f11( |
65 | // APCS-GNU: struct.s11* noalias sret |
66 | // AAPCS-LABEL: define arm_aapcscc i32 @f11() |
67 | struct s11 { int : 0; int f0; }; |
68 | struct s11 f11(void) {} |
69 | |
70 | // APCS-GNU-LABEL: define i32 @f12() |
71 | // AAPCS-LABEL: define arm_aapcscc i32 @f12() |
72 | union u12 { char f0; short f1; int f2; }; |
73 | union u12 f12(void) {} |
74 | |
75 | // APCS-GNU-LABEL: define void @f13( |
76 | // APCS-GNU: struct.s13* noalias sret |
77 | |
78 | // FIXME: This should return a float. |
79 | // AAPCS-FIXME: darm_aapcscc efine float @f13() |
80 | struct s13 { float f0; }; |
81 | struct s13 f13(void) {} |
82 | |
83 | // APCS-GNU-LABEL: define void @f14( |
84 | // APCS-GNU: union.u14* noalias sret |
85 | // AAPCS-LABEL: define arm_aapcscc i32 @f14() |
86 | union u14 { float f0; }; |
87 | union u14 f14(void) {} |
88 | |
89 | // APCS-GNU-LABEL: define void @f15() |
90 | // AAPCS-LABEL: define arm_aapcscc void @f15() |
91 | void f15(struct s7 a0) {} |
92 | |
93 | // APCS-GNU-LABEL: define void @f16() |
94 | // AAPCS-LABEL: define arm_aapcscc void @f16() |
95 | void f16(struct s8 a0) {} |
96 | |
97 | // APCS-GNU-LABEL: define i32 @f17() |
98 | // AAPCS-LABEL: define arm_aapcscc i32 @f17() |
99 | struct s17 { short f0 : 13; char f1 : 4; }; |
100 | struct s17 f17(void) {} |
101 | |
102 | // APCS-GNU-LABEL: define i32 @f18() |
103 | // AAPCS-LABEL: define arm_aapcscc i32 @f18() |
104 | struct s18 { short f0; char f1 : 4; }; |
105 | struct s18 f18(void) {} |
106 | |
107 | // APCS-GNU-LABEL: define void @f19( |
108 | // APCS-GNU: struct.s19* noalias sret |
109 | // AAPCS-LABEL: define arm_aapcscc i32 @f19() |
110 | struct s19 { int f0; struct s8 f1; }; |
111 | struct s19 f19(void) {} |
112 | |
113 | // APCS-GNU-LABEL: define void @f20( |
114 | // APCS-GNU: struct.s20* noalias sret |
115 | // AAPCS-LABEL: define arm_aapcscc i32 @f20() |
116 | struct s20 { struct s8 f1; int f0; }; |
117 | struct s20 f20(void) {} |
118 | |
119 | // APCS-GNU-LABEL: define i8 @f21() |
120 | // AAPCS-LABEL: define arm_aapcscc i32 @f21() |
121 | struct s21 { struct {} f1; int f0 : 4; }; |
122 | struct s21 f21(void) {} |
123 | |
124 | // APCS-GNU-LABEL: define i16 @f22() |
125 | // APCS-GNU-LABEL: define i32 @f23() |
126 | // APCS-GNU-LABEL: define i64 @f24() |
127 | // APCS-GNU-LABEL: define i128 @f25() |
128 | // APCS-GNU-LABEL: define i64 @f26() |
129 | // APCS-GNU-LABEL: define i128 @f27() |
130 | // AAPCS-LABEL: define arm_aapcscc i16 @f22() |
131 | // AAPCS-LABEL: define arm_aapcscc i32 @f23() |
132 | // AAPCS: define arm_aapcscc void @f24({{.*}} noalias sret |
133 | // AAPCS: define arm_aapcscc void @f25({{.*}} noalias sret |
134 | // AAPCS: define arm_aapcscc void @f26({{.*}} noalias sret |
135 | // AAPCS: define arm_aapcscc void @f27({{.*}} noalias sret |
136 | _Complex char f22(void) {} |
137 | _Complex short f23(void) {} |
138 | _Complex int f24(void) {} |
139 | _Complex long long f25(void) {} |
140 | _Complex float f26(void) {} |
141 | _Complex double f27(void) {} |
142 | |
143 | // APCS-GNU-LABEL: define i16 @f28() |
144 | // AAPCS-LABEL: define arm_aapcscc i16 @f28() |
145 | struct s28 { _Complex char f0; }; |
146 | struct s28 f28() {} |
147 | |
148 | // APCS-GNU-LABEL: define i32 @f29() |
149 | // AAPCS-LABEL: define arm_aapcscc i32 @f29() |
150 | struct s29 { _Complex short f0; }; |
151 | struct s29 f29() {} |
152 | |
153 | // APCS-GNU: define void @f30({{.*}} noalias sret |
154 | // AAPCS: define arm_aapcscc void @f30({{.*}} noalias sret |
155 | struct s30 { _Complex int f0; }; |
156 | struct s30 f30() {} |
157 | |
158 | // PR11905 |
159 | struct s31 { char x; }; |
160 | void f31(struct s31 s) { } |
161 | // AAPCS: @f31([1 x i32] %s.coerce) |
162 | // AAPCS: %s = alloca %struct.s31, align 1 |
163 | // AAPCS: [[TEMP:%.*]] = alloca [1 x i32], align 4 |
164 | // AAPCS: store [1 x i32] %s.coerce, [1 x i32]* [[TEMP]], align 4 |
165 | // APCS-GNU: @f31([1 x i32] %s.coerce) |
166 | // APCS-GNU: %s = alloca %struct.s31, align 1 |
167 | // APCS-GNU: [[TEMP:%.*]] = alloca [1 x i32], align 4 |
168 | // APCS-GNU: store [1 x i32] %s.coerce, [1 x i32]* [[TEMP]], align 4 |
169 | |
170 | // PR13562 |
171 | struct s32 { double x; }; |
172 | void f32(struct s32 s) { } |
173 | // AAPCS: @f32([1 x i64] %s.coerce) |
174 | // APCS-GNU: @f32([2 x i32] %s.coerce) |
175 | |
176 | // PR13350 |
177 | struct s33 { char buf[32*32]; }; |
178 | void f33(struct s33 s) { } |
179 | // APCS-GNU-LABEL: define void @f33(%struct.s33* byval align 4 %s) |
180 | // AAPCS-LABEL: define arm_aapcscc void @f33(%struct.s33* byval align 4 %s) |
181 | |
182 | // PR14048 |
183 | struct s34 { char c; }; |
184 | void f34(struct s34 s); |
185 | void g34(struct s34 *s) { f34(*s); } |
186 | // AAPCS: @g34(%struct.s34* %s) |
187 | // AAPCS: %[[a:.*]] = alloca [1 x i32] |
188 | // AAPCS: load [1 x i32], [1 x i32]* %[[a]] |
189 | |
190 | // rdar://12596507 |
191 | struct s35 |
192 | { |
193 | float v[18]; //make sure byval is on. |
194 | } __attribute__((aligned(16))); |
195 | typedef struct s35 s35_with_align; |
196 | |
197 | typedef __attribute__((neon_vector_type(4))) float float32x4_t; |
198 | static __attribute__((__always_inline__, __nodebug__)) float32x4_t vaddq_f32( |
199 | float32x4_t __a, float32x4_t __b) { |
200 | return __a + __b; |
201 | } |
202 | float32x4_t f35(int i, s35_with_align s1, s35_with_align s2) { |
203 | float32x4_t v = vaddq_f32(*(float32x4_t *)&s1, |
204 | *(float32x4_t *)&s2); |
205 | return v; |
206 | } |
207 | // APCS-GNU-LABEL: define <4 x float> @f35(i32 %i, %struct.s35* byval align 4, %struct.s35* byval align 4) |
208 | // APCS-GNU: %[[a:.*]] = alloca %struct.s35, align 16 |
209 | // APCS-GNU: %[[b:.*]] = bitcast %struct.s35* %[[a]] to i8* |
210 | // APCS-GNU: %[[c:.*]] = bitcast %struct.s35* %0 to i8* |
211 | // APCS-GNU: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align {{[0-9]+}} %[[b]], i8* align {{[0-9]+}} %[[c]] |
212 | // APCS-GNU: %[[d:.*]] = bitcast %struct.s35* %[[a]] to <4 x float>* |
213 | // APCS-GNU: load <4 x float>, <4 x float>* %[[d]], align 16 |
214 | |
215 | // AAPCS-LABEL: define arm_aapcscc <4 x float> @f35(i32 %i, %struct.s35* byval align 4 %s1, %struct.s35* byval align 4 %s2) |
216 | // AAPCS: %[[a_addr:.*]] = alloca <4 x float>, align 16 |
217 | // AAPCS: %[[b_addr:.*]] = alloca <4 x float>, align 16 |
218 | // AAPCS: %[[p1:.*]] = bitcast %struct.s35* %s1 to <4 x float>* |
219 | // AAPCS: %[[a:.*]] = load <4 x float>, <4 x float>* %[[p1]], align 4 |
220 | // AAPCS: %[[p2:.*]] = bitcast %struct.s35* %s2 to <4 x float>* |
221 | // AAPCS: %[[b:.*]] = load <4 x float>, <4 x float>* %[[p2]], align 4 |
222 | // AAPCS: store <4 x float> %[[a]], <4 x float>* %[[a_addr]], align 16 |
223 | // AAPCS: store <4 x float> %[[b]], <4 x float>* %[[b_addr]], align 16 |
224 | |