Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / ARM / GlobalISel / arm-isel.ll
blob2161b40ee939316c4ee12c7b206c47519279f8d2
1 ; RUN: llc -mtriple arm-unknown -mattr=+vfp2,+v6 -global-isel %s -o - | FileCheck %s
3 define void @test_void_return() {
4 ; CHECK-LABEL: test_void_return:
5 ; CHECK: bx lr
6 entry:
7   ret void
10 define i32 @test_constant_return_i32() {
11 ; CHECK-LABEL: test_constant_return_i32:
12 ; CHECK: mov r0, #42
13 ; CHECK: bx lr
14 entry:
15   ret i32 42
18 define zeroext i1 @test_zext_i1(i1 %x) {
19 ; CHECK-LABEL: test_zext_i1
20 ; CHECK: and r0, r0, #1
21 ; CHECK: bx lr
22 entry:
23   ret i1 %x
26 define signext i1 @test_sext_i1(i1 %x) {
27 ; CHECK-LABEL: test_sext_i1
28 ; CHECK: mov    r1, #31
29 ; CHECK: lsl    r0, r0, r1
30 ; CHECK: asr    r0, r0, r1
31 ; CHECK: bx lr
32 entry:
33   ret i1 %x
36 define zeroext i8 @test_ext_i8(i8 %x) {
37 ; CHECK-LABEL: test_ext_i8:
38 ; CHECK: uxtb r0, r0
39 ; CHECK: bx lr
41 entry:
42   ret i8 %x
45 define signext i16 @test_ext_i16(i16 %x) {
46 ; CHECK-LABEL: test_ext_i16:
47 ; CHECK: mov    r1, #16
48 ; CHECK: lsl    r0, r0, r1
49 ; CHECK: asr    r0, r0, r1
50 ; CHECK: bx lr
51 entry:
52   ret i16 %x
55 define void @test_trunc_i32_i16(i32 %v, ptr %p) {
56 ; CHECK-LABEL: test_trunc_i32_i16:
57 ; The trunc doesn't result in any instructions, but we
58 ; expect the store to be explicitly 16-bit.
59 ; CHECK: strh r0, [r1]
60 ; CHECK: bx lr
61 entry:
62   %v16 = trunc i32 %v to i16
63   store i16 %v16, ptr %p
64   ret void
67 define void @test_trunc_i32_i8(i32 %v, ptr %p) {
68 ; CHECK-LABEL: test_trunc_i32_i8:
69 ; The trunc doesn't result in any instructions, but we
70 ; expect the store to be explicitly 8-bit.
71 ; CHECK: strb r0, [r1]
72 ; CHECK: bx lr
73 entry:
74   %v8 = trunc i32 %v to i8
75   store i8 %v8, ptr %p
76   ret void
79 define i8 @test_add_i8(i8 %x, i8 %y) {
80 ; CHECK-LABEL: test_add_i8:
81 ; CHECK: add r0, r0, r1
82 ; CHECK: bx lr
83 entry:
84   %sum = add i8 %x, %y
85   ret i8 %sum
88 define i16 @test_add_i16(i16 %x, i16 %y) {
89 ; CHECK-LABEL: test_add_i16:
90 ; CHECK: add r0, r0, r1
91 ; CHECK: bx lr
92 entry:
93   %sum = add i16 %x, %y
94   ret i16 %sum
97 define i32 @test_add_i32(i32 %x, i32 %y) {
98 ; CHECK-LABEL: test_add_i32:
99 ; CHECK: add r0, r0, r1
100 ; CHECK: bx lr
101 entry:
102   %sum = add i32 %x, %y
103   ret i32 %sum
106 define i8 @test_sub_i8(i8 %x, i8 %y) {
107 ; CHECK-LABEL: test_sub_i8:
108 ; CHECK: sub r0, r0, r1
109 ; CHECK: bx lr
110 entry:
111   %sum = sub i8 %x, %y
112   ret i8 %sum
115 define i16 @test_sub_i16(i16 %x, i16 %y) {
116 ; CHECK-LABEL: test_sub_i16:
117 ; CHECK: sub r0, r0, r1
118 ; CHECK: bx lr
119 entry:
120   %sum = sub i16 %x, %y
121   ret i16 %sum
124 define i32 @test_sub_i32(i32 %x, i32 %y) {
125 ; CHECK-LABEL: test_sub_i32:
126 ; CHECK: sub r0, r0, r1
127 ; CHECK: bx lr
128 entry:
129   %sum = sub i32 %x, %y
130   ret i32 %sum
133 define i8 @test_mul_i8(i8 %x, i8 %y) {
134 ; CHECK-LABEL: test_mul_i8:
135 ; CHECK: mul r0, r0, r1
136 ; CHECK: bx lr
137 entry:
138   %sum = mul i8 %x, %y
139   ret i8 %sum
142 define i16 @test_mul_i16(i16 %x, i16 %y) {
143 ; CHECK-LABEL: test_mul_i16:
144 ; CHECK: mul r0, r0, r1
145 ; CHECK: bx lr
146 entry:
147   %sum = mul i16 %x, %y
148   ret i16 %sum
151 define i32 @test_mul_i32(i32 %x, i32 %y) {
152 ; CHECK-LABEL: test_mul_i32:
153 ; CHECK: mul r0, r0, r1
154 ; CHECK: bx lr
155 entry:
156   %sum = mul i32 %x, %y
157   ret i32 %sum
160 define i8 @test_and_i8(i8 %x, i8 %y) {
161 ; CHECK-LABEL: test_and_i8:
162 ; CHECK: and r0, r0, r1
163 ; CHECK: bx lr
164 entry:
165   %sum = and i8 %x, %y
166   ret i8 %sum
169 define i16 @test_and_i16(i16 %x, i16 %y) {
170 ; CHECK-LABEL: test_and_i16:
171 ; CHECK: and r0, r0, r1
172 ; CHECK: bx lr
173 entry:
174   %sum = and i16 %x, %y
175   ret i16 %sum
178 define i32 @test_and_i32(i32 %x, i32 %y) {
179 ; CHECK-LABEL: test_and_i32:
180 ; CHECK: and r0, r0, r1
181 ; CHECK: bx lr
182 entry:
183   %sum = and i32 %x, %y
184   ret i32 %sum
187 define i8 @test_or_i8(i8 %x, i8 %y) {
188 ; CHECK-LABEL: test_or_i8:
189 ; CHECK: orr r0, r0, r1
190 ; CHECK: bx lr
191 entry:
192   %sum = or i8 %x, %y
193   ret i8 %sum
196 define i16 @test_or_i16(i16 %x, i16 %y) {
197 ; CHECK-LABEL: test_or_i16:
198 ; CHECK: orr r0, r0, r1
199 ; CHECK: bx lr
200 entry:
201   %sum = or i16 %x, %y
202   ret i16 %sum
205 define i32 @test_or_i32(i32 %x, i32 %y) {
206 ; CHECK-LABEL: test_or_i32:
207 ; CHECK: orr r0, r0, r1
208 ; CHECK: bx lr
209 entry:
210   %sum = or i32 %x, %y
211   ret i32 %sum
214 define i8 @test_xor_i8(i8 %x, i8 %y) {
215 ; CHECK-LABEL: test_xor_i8:
216 ; CHECK: eor r0, r0, r1
217 ; CHECK: bx lr
218 entry:
219   %sum = xor i8 %x, %y
220   ret i8 %sum
223 define i16 @test_xor_i16(i16 %x, i16 %y) {
224 ; CHECK-LABEL: test_xor_i16:
225 ; CHECK: eor r0, r0, r1
226 ; CHECK: bx lr
227 entry:
228   %sum = xor i16 %x, %y
229   ret i16 %sum
232 define i32 @test_xor_i32(i32 %x, i32 %y) {
233 ; CHECK-LABEL: test_xor_i32:
234 ; CHECK: eor r0, r0, r1
235 ; CHECK: bx lr
236 entry:
237   %sum = xor i32 %x, %y
238   ret i32 %sum
241 define i32 @test_stack_args_i32(i32 %p0, i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) {
242 ; CHECK-LABEL: test_stack_args_i32:
243 ; CHECK: add [[P5ADDR:r[0-9]+]], sp, #4
244 ; CHECK: ldr [[P5:r[0-9]+]], {{.*}}[[P5ADDR]]
245 ; CHECK: add r0, r2, [[P5]]
246 ; CHECK: bx lr
247 entry:
248   %sum = add i32 %p2, %p5
249   ret i32 %sum
252 define i16 @test_stack_args_mixed(i32 %p0, i16 %p1, i8 %p2, i1 %p3, i8 %p4, i16 %p5) {
253 ; CHECK-LABEL: test_stack_args_mixed:
254 ; CHECK: add [[P5ADDR:r[0-9]+]], sp, #4
255 ; CHECK: ldr [[P5:r[0-9]+]], {{.*}}[[P5ADDR]]
256 ; CHECK: add r0, r1, [[P5]]
257 ; CHECK: bx lr
258 entry:
259   %sum = add i16 %p1, %p5
260   ret i16 %sum
263 define i16 @test_stack_args_zeroext(i32 %p0, i16 %p1, i8 %p2, i1 %p3, i16 zeroext %p4) {
264 ; CHECK-LABEL: test_stack_args_zeroext:
265 ; CHECK: mov [[P4ADDR:r[0-9]+]], sp
266 ; CHECK: ldr [[P4:r[0-9]+]], {{.*}}[[P4ADDR]]
267 ; CHECK: add r0, r1, [[P4]]
268 ; CHECK: bx lr
269 entry:
270   %sum = add i16 %p1, %p4
271   ret i16 %sum
274 define i8 @test_stack_args_signext(i32 %p0, i16 %p1, i8 %p2, i1 %p3, i8 signext %p4) {
275 ; CHECK-LABEL: test_stack_args_signext:
276 ; CHECK: mov [[P4ADDR:r[0-9]+]], sp
277 ; CHECK: ldr [[P4:r[0-9]+]], {{.*}}[[P4ADDR]]
278 ; CHECK: add r0, r2, [[P4]]
279 ; CHECK: bx lr
280 entry:
281   %sum = add i8 %p2, %p4
282   ret i8 %sum
285 define i8 @test_stack_args_noext(i32 %p0, i16 %p1, i8 %p2, i1 %p3, i8 %p4) {
286 ; CHECK-LABEL: test_stack_args_noext:
287 ; CHECK: mov [[P4ADDR:r[0-9]+]], sp
288 ; CHECK: ldr [[P4:r[0-9]+]], {{.*}}[[P4ADDR]]
289 ; CHECK: add r0, r2, [[P4]]
290 ; CHECK: bx lr
291 entry:
292   %sum = add i8 %p2, %p4
293   ret i8 %sum
296 define i32 @test_ptr_arg_in_reg(ptr %p) {
297 ; CHECK-LABEL: test_ptr_arg_in_reg:
298 ; CHECK: ldr r0, [r0]
299 ; CHECK: bx lr
300 entry:
301   %v = load i32, ptr %p
302   ret i32 %v
305 define i32 @test_ptr_arg_on_stack(i32 %f0, i32 %f1, i32 %f2, i32 %f3, ptr %p) {
306 ; CHECK-LABEL: test_ptr_arg_on_stack:
307 ; CHECK: mov r0, sp
308 ; CHECK: ldr r0, [r0]
309 ; CHECK: ldr r0, [r0]
310 ; CHECK: bx lr
311 entry:
312   %v = load i32, ptr %p
313   ret i32 %v
316 define ptr @test_ptr_ret(ptr %p) {
317 ; CHECK-LABEL: test_ptr_ret:
318 ; CHECK: ldr r0, [r0]
319 ; CHECK: bx lr
320 entry:
321   %v = load ptr, ptr %p
322   ret ptr %v
325 define arm_aapcs_vfpcc float @test_float_hard(float %f0, float %f1) {
326 ; CHECK-LABEL: test_float_hard:
327 ; CHECK: vadd.f32 s0, s0, s1
328 ; CHECK: bx lr
329 entry:
330   %v = fadd float %f0, %f1
331   ret float %v
334 define arm_aapcscc float @test_float_softfp(float %f0, float %f1) {
335 ; CHECK-LABEL: test_float_softfp:
336 ; CHECK-DAG: vmov [[F0:s[0-9]+]], r0
337 ; CHECK-DAG: vmov [[F1:s[0-9]+]], r1
338 ; CHECK: vadd.f32 [[FV:s[0-9]+]], [[F0]], [[F1]]
339 ; CHECK: vmov r0, [[FV]]
340 ; CHECK: bx lr
341 entry:
342   %v = fadd float %f0, %f1
343   ret float %v
346 define arm_aapcs_vfpcc double @test_double_hard(double %f0, double %f1) {
347 ; CHECK-LABEL: test_double_hard:
348 ; CHECK: vadd.f64 d0, d0, d1
349 ; CHECK: bx lr
350 entry:
351   %v = fadd double %f0, %f1
352   ret double %v
355 define arm_aapcscc double @test_double_softfp(double %f0, double %f1) {
356 ; CHECK-LABEL: test_double_softfp:
357 ; CHECK-DAG: vmov [[F0:d[0-9]+]], r0, r1
358 ; CHECK-DAG: vmov [[F1:d[0-9]+]], r2, r3
359 ; CHECK: vadd.f64 [[FV:d[0-9]+]], [[F0]], [[F1]]
360 ; CHECK: vmov r0, r1, [[FV]]
361 ; CHECK: bx lr
362 entry:
363   %v = fadd double %f0, %f1
364   ret double %v
367 define arm_aapcscc i32 @test_cmp_i32_eq(i32 %a, i32 %b) {
368 ; CHECK-LABEL: test_cmp_i32_eq:
369 ; CHECK: mov [[V:r[0-9]+]], #0
370 ; CHECK: cmp r0, r1
371 ; CHECK: moveq [[V]], #1
372 ; CHECK: and r0, [[V]], #1
373 ; CHECK: bx lr
374 entry:
375   %v = icmp eq i32 %a, %b
376   %r = zext i1 %v to i32
377   ret i32 %r
380 define arm_aapcscc i32 @test_cmp_ptr_neq(ptr %a, ptr %b) {
381 ; CHECK-LABEL: test_cmp_ptr_neq:
382 ; CHECK: mov [[V:r[0-9]+]], #0
383 ; CHECK: cmp r0, r1
384 ; CHECK: movne [[V]], #1
385 ; CHECK: and r0, [[V]], #1
386 ; CHECK: bx lr
387 entry:
388   %v = icmp ne ptr %a, %b
389   %r = zext i1 %v to i32
390   ret i32 %r
393 define arm_aapcscc i32 @test_cmp_i16_slt(i16 %a, i16 %b) {
394 ; CHECK-LABEL: test_cmp_i16_slt:
395 ; CHECK-DAG: mov [[V:r[0-9]+]], #0
396 ; CHECK: cmp r0, r1
397 ; CHECK: movlt [[V]], #1
398 ; CHECK: and r0, [[V]], #1
399 ; CHECK: bx lr
400 entry:
401   %v = icmp slt i16 %a, %b
402   %r = zext i1 %v to i32
403   ret i32 %r
406 define arm_aapcscc i32 @test_select_i32(i32 %a, i32 %b, i1 %cond) {
407 ; CHECK-LABEL: test_select_i32
408 ; CHECK: tst r2, #1
409 ; CHECK: moveq r0, r1
410 ; CHECK: bx lr
411 entry:
412   %r = select i1 %cond, i32 %a, i32 %b
413   ret i32 %r
416 define arm_aapcscc ptr @test_select_ptr(ptr %a, ptr %b, i1 %cond) {
417 ; CHECK-LABEL: test_select_ptr
418 ; CHECK: tst r2, #1
419 ; CHECK: moveq r0, r1
420 ; CHECK: bx lr
421 entry:
422   %r = select i1 %cond, ptr %a, ptr %b
423   ret ptr %r
426 define arm_aapcscc void @test_br() {
427 ; CHECK-LABEL: test_br
428 ; CHECK: [[LABEL:.L[[:alnum:]_]+]]:
429 ; CHECK: b [[LABEL]]
430 entry:
431   br label %infinite
433 infinite:
434   br label %infinite
437 declare arm_aapcscc void @brcond1()
438 declare arm_aapcscc void @brcond2()
440 define arm_aapcscc void @test_brcond(i32 %n) {
441 ; CHECK-LABEL: test_brcond
442 ; CHECK: cmp r0
443 ; CHECK-NEXT: movgt [[RCMP:r[0-9]+]], #1
444 ; CHECK: tst [[RCMP]], #1
445 ; CHECK-NEXT: beq [[FALSE:.L[[:alnum:]_]+]]
446 ; CHECK: bl brcond1
447 ; CHECK: [[FALSE]]:
448 ; CHECK: bl brcond2
449 entry:
450   %cmp = icmp sgt i32 %n, 0
451   br i1 %cmp, label %if.true, label %if.false
453 if.true:
454   call arm_aapcscc void @brcond1()
455   br label %if.end
457 if.false:
458   call arm_aapcscc void @brcond2()
459   br label %if.end
461 if.end:
462   ret void