xref: /llvm-project/llvm/test/CodeGen/ARM/inlineasm-operand-implicit-cast.ll (revision bdaa181007a46d317a1665acb8234eddeee82815)
1; RUN: llc -mtriple armv7-arm-linux-gnueabihf -O2 -mcpu=cortex-a7 < %s | FileCheck %s
2; RUN: llc -mtriple armv7-arm-linux-gnueabihf -O2 -mcpu=cortex-a7 -early-live-intervals < %s | FileCheck %s
3
4%struct.twofloat = type { float, float }
5%struct.twodouble = type { double, double }
6
7; Check support for returning a float in GPR with soft float ABI
8define arm_aapcscc float @zerobits_float_soft() #0 {
9; CHECK-LABEL: zerobits_float_soft
10; CHECK: mov r0, #0
11  %1 = tail call float asm "mov ${0}, #0", "=&r"()
12  ret float %1
13}
14
15; Check support for returning a double in GPR with soft float ABI
16define arm_aapcscc double @zerobits_double_soft() #0 {
17; CHECK-LABEL: zerobits_double_soft
18; CHECK: mov r0, #0
19; CHECK-NEXT: mov r1, #0
20  %1 = tail call double asm "mov ${0:Q}, #0\0Amov ${0:R}, #0", "=&r"()
21  ret double %1
22}
23
24; Check support for returning a float in GPR with matching float input with
25; soft float ABI
26define arm_aapcscc float @flt_gpr_matching_in_op_soft(float %f) #0 {
27; CHECK-LABEL: flt_gpr_matching_in_op_soft
28; CHECK: mov r0, r0
29  %1 = call float asm "mov $0, $1", "=&r,0"(float %f)
30  ret float %1
31}
32
33; Check support for returning a double in GPR with matching double input with
34; soft float ABI
35define arm_aapcscc double @dbl_gpr_matching_in_op_soft(double %d) #0 {
36; CHECK-LABEL: dbl_gpr_matching_in_op_soft
37; CHECK: mov r1, r0
38  %1 = call double asm "mov ${0:R}, ${1:Q}", "=&r,0"(double %d)
39  ret double %1
40}
41
42; Check support for returning a float in specific GPR with matching float input
43; with soft float ABI
44define arm_aapcscc float @flt_gpr_matching_spec_reg_in_op_soft(float %f) #0 {
45; CHECK-LABEL: flt_gpr_matching_spec_reg_in_op_soft
46; CHECK: mov r3, r3
47  %1 = call float asm "mov $0, $1", "=&{r3},0"(float %f)
48  ret float %1
49}
50
51; Check support for returning a double in specific GPR with matching double
52; input with soft float ABI
53define arm_aapcscc double @dbl_gpr_matching_spec_reg_in_op_soft(double %d) #0 {
54; CHECK-LABEL: dbl_gpr_matching_spec_reg_in_op_soft
55; CHECK: mov r3, r2
56  %1 = call double asm "mov ${0:R}, ${1:Q}", "=&{r2},0"(double %d)
57  ret double %1
58}
59
60; Check support for returning several float in GPR
61define arm_aapcscc float @zerobits_float_convoluted_soft() #0 {
62; CHECK-LABEL: zerobits_float_convoluted_soft
63; CHECK: mov r0, #0
64; CHECK-NEXT: mov r1, #0
65  %1 = call { float, float } asm "mov $0, #0; mov $1, #0", "=r,=r"()
66  %asmresult = extractvalue { float, float } %1, 0
67  %asmresult1 = extractvalue { float, float } %1, 1
68  %add = fadd float %asmresult, %asmresult1
69  ret float %add
70}
71
72; Check support for returning several double in GPR
73define double @zerobits_double_convoluted_soft() #0 {
74; CHECK-LABEL: zerobits_double_convoluted_soft
75; CHECK: mov r0, #0
76; CHECK-NEXT: mov r1, #0
77; CHECK-NEXT: mov r2, #0
78; CHECK-NEXT: mov r3, #0
79  %1 = call { double, double } asm "mov ${0:Q}, #0; mov ${0:R}, #0; mov ${1:Q}, #0; mov ${1:R}, #0", "=r,=r"()
80  %asmresult = extractvalue { double, double } %1, 0
81  %asmresult1 = extractvalue { double, double } %1, 1
82  %add = fadd double %asmresult, %asmresult1
83  ret double %add
84}
85
86; Check support for returning several floats in GPRs with matching float inputs
87; with soft float ABI
88define arm_aapcscc float @flt_gprs_matching_in_op_soft(float %f1, float %f2) #0 {
89; CHECK-LABEL: flt_gprs_matching_in_op_soft
90; CHECK: mov r0, r0
91; CHECK-NEXT: mov r1, r1
92  %1 = call { float, float } asm "mov $0, $2; mov $1, $3", "=&r,=&r,0,1"(float %f1, float %f2)
93  %asmresult1 = extractvalue { float, float } %1, 0
94  %asmresult2 = extractvalue { float, float } %1, 1
95  %add = fadd float %asmresult1, %asmresult2
96  ret float %add
97}
98
99; Check support for returning several double in GPRs with matching double input
100; with soft float ABI
101define arm_aapcscc double @dbl_gprs_matching_in_op_soft(double %d1, double %d2) #0 {
102; CHECK-LABEL: dbl_gprs_matching_in_op_soft
103; CHECK: mov r1, r0
104; CHECK-NEXT: mov r3, r2
105  %1 = call { double, double } asm "mov ${0:R}, ${2:Q}; mov ${1:R}, ${3:Q}", "=&r,=&r,0,1"(double %d1, double %d2)
106  %asmresult1 = extractvalue { double, double } %1, 0
107  %asmresult2 = extractvalue { double, double } %1, 1
108  %add = fadd double %asmresult1, %asmresult2
109  ret double %add
110}
111
112; Check support for returning several float in specific GPRs with matching
113; float input with soft float ABI
114define arm_aapcscc float @flt_gprs_matching_spec_reg_in_op_soft(float %f1, float %f2) #0 {
115; CHECK-LABEL: flt_gprs_matching_spec_reg_in_op_soft
116; CHECK: mov r3, r3
117; CHECK-NEXT: mov r4, r4
118  %1 = call { float, float } asm "mov $0, $2; mov $1, $3", "=&{r3},=&{r4},0,1"(float %f1, float %f2)
119  %asmresult1 = extractvalue { float, float } %1, 0
120  %asmresult2 = extractvalue { float, float } %1, 1
121  %add = fadd float %asmresult1, %asmresult2
122  ret float %add
123}
124
125; Check support for returning several double in specific GPRs with matching
126; double input with soft float ABI
127define arm_aapcscc double @dbl_gprs_matching_spec_reg_in_op_soft(double %d1, double %d2) #0 {
128; CHECK-LABEL: dbl_gprs_matching_spec_reg_in_op_soft
129; CHECK: mov r3, r2
130; CHECK-NEXT: mov r5, r4
131  %1 = call { double, double } asm "mov ${0:R}, ${2:Q}; mov ${1:R}, ${3:Q}", "=&{r2},=&{r4},0,1"(double %d1, double %d2)
132  %asmresult1 = extractvalue { double, double } %1, 0
133  %asmresult2 = extractvalue { double, double } %1, 1
134  %add = fadd double %asmresult1, %asmresult2
135  ret double %add
136}
137
138attributes #0 = { nounwind "target-features"="-d32,+vfp2,+vfp3" "use-soft-float"="true" }
139
140
141; Check support for returning a float in GPR with hard float ABI
142define float @zerobits_float_hard() #1 {
143; CHECK-LABEL: zerobits_float_hard
144; CHECK: mov r0, #0
145; CHECK: vmov s0, r0
146  %1 = tail call float asm "mov ${0}, #0", "=&r"()
147  ret float %1
148}
149
150; Check support for returning a double in GPR with hard float ABI
151define double @zerobits_double_hard() #1 {
152; CHECK-LABEL: zerobits_double_hard
153; CHECK: mov r0, #0
154; CHECK-NEXT: mov r1, #0
155; CHECK: vmov d0, r0, r1
156  %1 = tail call double asm "mov ${0:Q}, #0\0Amov ${0:R}, #0", "=&r"()
157  ret double %1
158}
159
160; Check support for returning a float in GPR with matching float input with
161; hard float ABI
162define float @flt_gpr_matching_in_op_hard(float %f) #1 {
163; CHECK-LABEL: flt_gpr_matching_in_op_hard
164; CHECK: vmov r0, s0
165; CHECK: mov r0, r0
166; CHECK: vmov s0, r0
167  %1 = call float asm "mov $0, $1", "=&r,0"(float %f)
168  ret float %1
169}
170
171; Check support for returning a double in GPR with matching double input with
172; hard float ABI
173define double @dbl_gpr_matching_in_op_hard(double %d) #1 {
174; CHECK-LABEL: dbl_gpr_matching_in_op_hard
175; CHECK: vmov r0, r1, d0
176; CHECK: mov r1, r0
177; CHECK: vmov d0, r0, r1
178  %1 = call double asm "mov ${0:R}, ${1:Q}", "=&r,0"(double %d)
179  ret double %1
180}
181
182; Check support for returning a float in specific GPR with matching float
183; input with hard float ABI
184define float @flt_gpr_matching_spec_reg_in_op_hard(float %f) #1 {
185; CHECK-LABEL: flt_gpr_matching_spec_reg_in_op_hard
186; CHECK: vmov r3, s0
187; CHECK: mov r3, r3
188; CHECK: vmov s0, r3
189  %1 = call float asm "mov $0, $1", "=&{r3},0"(float %f)
190  ret float %1
191}
192
193; Check support for returning a double in specific GPR with matching double
194; input with hard float ABI
195define double @dbl_gpr_matching_spec_reg_in_op_hard(double %d) #1 {
196; CHECK-LABEL: dbl_gpr_matching_spec_reg_in_op_hard
197; CHECK: vmov r2, r3, d0
198; CHECK: mov r3, r2
199; CHECK: vmov d0, r2, r3
200  %1 = call double asm "mov ${0:R}, ${1:Q}", "=&{r2},0"(double %d)
201  ret double %1
202}
203
204; Check support for returning several float in GPR
205define %struct.twofloat @zerobits_float_convoluted_hard() #1 {
206; CHECK-LABEL: zerobits_float_convoluted_hard
207; CHECK: mov r0, #0
208; CHECK-NEXT: mov r1, #0
209; CHECK: vmov s0, r0
210; CHECK-NEXT: vmov s1, r1
211  %1 = call { float, float } asm "mov $0, #0; mov $1, #0", "=r,=r"()
212  %asmresult1 = extractvalue { float, float } %1, 0
213  %asmresult2 = extractvalue { float, float } %1, 1
214  %partialres = insertvalue %struct.twofloat undef, float %asmresult1, 0
215  %res = insertvalue %struct.twofloat %partialres, float %asmresult2, 1
216  ret %struct.twofloat %res
217}
218
219; Check support for returning several double in GPR
220define %struct.twodouble @zerobits_double_convoluted_hard() #1 {
221; CHECK-LABEL: zerobits_double_convoluted_hard
222; CHECK: mov r0, #0
223; CHECK-NEXT: mov r1, #0
224; CHECK-NEXT: mov r2, #0
225; CHECK-NEXT: mov r3, #0
226; CHECK: vmov d0, r0, r1
227; CHECK-NEXT: vmov d1, r2, r3
228  %1 = call { double, double } asm "mov ${0:Q}, #0; mov ${0:R}, #0; mov ${1:Q}, #0; mov ${1:R}, #0", "=r,=r"()
229  %asmresult1 = extractvalue { double, double } %1, 0
230  %asmresult2 = extractvalue { double, double } %1, 1
231  %partialres = insertvalue %struct.twodouble undef, double %asmresult1, 0
232  %res = insertvalue %struct.twodouble %partialres, double %asmresult2, 1
233  ret %struct.twodouble %res
234}
235
236; Check support for returning several floats in GPRs with matching float inputs
237; with hard float ABI
238define %struct.twofloat @flt_gprs_matching_in_op_hard(float %f1, float %f2) #1 {
239; CHECK-LABEL: flt_gprs_matching_in_op_hard
240; CHECK: vmov r0, s0
241; CHECK-NEXT: vmov r1, s1
242; CHECK: mov r0, r0
243; CHECK-NEXT: mov r1, r1
244; CHECK: vmov s0, r0
245; CHECK-NEXT: vmov s1, r1
246  %1 = call { float, float } asm "mov $0, $2; mov $1, $3", "=&r,=&r,0,1"(float %f1, float %f2)
247  %asmresult1 = extractvalue { float, float } %1, 0
248  %asmresult2 = extractvalue { float, float } %1, 1
249  %partialres = insertvalue %struct.twofloat undef, float %asmresult1, 0
250  %res = insertvalue %struct.twofloat %partialres, float %asmresult2, 1
251  ret %struct.twofloat %res
252}
253
254; Check support for returning several double in GPRs with matching double input
255; with hard float ABI
256define %struct.twodouble @dbl_gprs_matching_in_op_hard(double %d1, double %d2) #1 {
257; CHECK-LABEL: dbl_gprs_matching_in_op_hard
258; CHECK: vmov r0, r1, d0
259; CHECK-NEXT: vmov r2, r3, d1
260; CHECK: mov r1, r0
261; CHECK-NEXT: mov r3, r2
262; CHECK: vmov d0, r0, r1
263; CHECK-NEXT: vmov d1, r2, r3
264  %1 = call { double, double } asm "mov ${0:R}, ${2:Q}; mov ${1:R}, ${3:Q}", "=&r,=&r,0,1"(double %d1, double %d2)
265  %asmresult1 = extractvalue { double, double } %1, 0
266  %asmresult2 = extractvalue { double, double } %1, 1
267  %partialres = insertvalue %struct.twodouble undef, double %asmresult1, 0
268  %res = insertvalue %struct.twodouble %partialres, double %asmresult2, 1
269  ret %struct.twodouble %res
270}
271
272; Check support for returning several float in specific GPRs with matching
273; float input with hard float ABI
274define %struct.twofloat @flt_gprs_matching_spec_reg_in_op_hard(float %f1, float %f2) #1 {
275; CHECK-LABEL: flt_gprs_matching_spec_reg_in_op_hard
276; CHECK: vmov r3, s0
277; CHECK-NEXT: vmov r4, s1
278; CHECK: mov r3, r3
279; CHECK-NEXT: mov r4, r4
280; CHECK: vmov s0, r3
281; CHECK-NEXT: vmov s1, r4
282  %1 = call { float, float } asm "mov $0, $2; mov $1, $3", "=&{r3},=&{r4},0,1"(float %f1, float %f2)
283  %asmresult1 = extractvalue { float, float } %1, 0
284  %asmresult2 = extractvalue { float, float } %1, 1
285  %partialres = insertvalue %struct.twofloat undef, float %asmresult1, 0
286  %res = insertvalue %struct.twofloat %partialres, float %asmresult2, 1
287  ret %struct.twofloat %res
288}
289
290; Check support for returning several double in specific GPRs with matching
291; double input with hard float ABI
292define %struct.twodouble @dbl_gprs_matching_spec_reg_in_op_hard(double %d1, double %d2) #1 {
293; CHECK-LABEL: dbl_gprs_matching_spec_reg_in_op_hard
294; CHECK: vmov r2, r3, d0
295; CHECK-NEXT: vmov r4, r5, d1
296; CHECK: mov r3, r2
297; CHECK-NEXT: mov r5, r4
298; CHECK: vmov d0, r2, r3
299; CHECK-NEXT: vmov d1, r4, r5
300  %1 = call { double, double } asm "mov ${0:R}, ${2:Q}; mov ${1:R}, ${3:Q}", "=&{r2},=&{r4},0,1"(double %d1, double %d2)
301  %asmresult1 = extractvalue { double, double } %1, 0
302  %asmresult2 = extractvalue { double, double } %1, 1
303  %partialres = insertvalue %struct.twodouble undef, double %asmresult1, 0
304  %res = insertvalue %struct.twodouble %partialres, double %asmresult2, 1
305  ret %struct.twodouble %res
306}
307
308attributes #1 = { nounwind "target-features"="-d32,+vfp2,+vfp3" "use-soft-float"="false" }
309