Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / test / CodeGen / ARM / shift-i64.ll
blobc9cd7d6ab9601906dbdc5dffb740f9a29c715787
1 ; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s
2 ; RUN: llc -mtriple=armv6m-eabi %s -o - | FileCheck %s --check-prefix=EXPAND
4 define i64 @test_shl(i64 %val, i64 %amt) {
5 ; CHECK-LABEL: test_shl:
6 ; EXPAND-LABEL: test_shl:
7   ; First calculate the hi part when the shift amount is small enough that it
8   ; contains components from both halves. It'll be returned in r1 so that's a
9   ; reasonable place for it to end up.
10 ; CHECK: rsb [[REVERSE_SHIFT:.*]], r2, #32
11 ; CHECK: lsr [[TMP:.*]], r0, [[REVERSE_SHIFT]]
12 ; CHECK: orr r1, [[TMP]], r1, lsl r2
14   ; Check whether the shift was in fact small (< 32 bits).
15 ; CHECK: sub [[EXTRA_SHIFT:.*]], r2, #32
16 ; CHECK: cmp [[EXTRA_SHIFT]], #0
18   ; If not, the high part of the answer is just the low part shifted by the
19   ; excess.
20 ; CHECK: lslge r1, r0, [[EXTRA_SHIFT]]
22   ; The low part is either a direct shift (1st inst) or 0. We can reuse the same
23   ; NZCV.
24 ; CHECK: lsl r0, r0, r2
25 ; CHECK: movge r0, #0
27 ; EXPAND:      push {[[REG:r[0-9]+]], lr}
28 ; EXPAND-NEXT: bl __aeabi_llsl
29 ; EXPAND-NEXT: pop {[[REG]], pc}
30   %res = shl i64 %val, %amt
31   ret i64 %res
34 ; Explanation for lshr is pretty much the reverse of shl.
35 define i64 @test_lshr(i64 %val, i64 %amt) {
36 ; CHECK-LABEL: test_lshr:
37 ; EXPAND-LABEL: test_lshr:
38 ; CHECK: rsb [[REVERSE_SHIFT:.*]], r2, #32
39 ; CHECK: lsr r0, r0, r2
40 ; CHECK: orr r0, r0, r1, lsl [[REVERSE_SHIFT]]
41 ; CHECK: sub [[EXTRA_SHIFT:.*]], r2, #32
42 ; CHECK: cmp [[EXTRA_SHIFT]], #0
43 ; CHECK: lsrge r0, r1, [[EXTRA_SHIFT]]
44 ; CHECK: lsr r1, r1, r2
45 ; CHECK: movge r1, #0
47 ; EXPAND:      push {[[REG:r[0-9]+]], lr}
48 ; EXPAND-NEXT: bl __aeabi_llsr
49 ; EXPAND-NEXT: pop {[[REG]], pc}
50   %res = lshr i64 %val, %amt
51   ret i64 %res
54 ; One minor difference for ashr: the high bits must be "hi >> 31" if the shift
55 ; amount is large to get the right sign bit.
56 define i64 @test_ashr(i64 %val, i64 %amt) {
57 ; CHECK-LABEL: test_ashr:
58 ; EXPAND-LABEL: test_ashr:
59 ; CHECK: sub [[EXTRA_SHIFT:.*]], r2, #32
60 ; CHECK: asr [[HI_TMP:.*]], r1, r2
61 ; CHECK: lsr r0, r0, r2
62 ; CHECK: rsb [[REVERSE_SHIFT:.*]], r2, #32
63 ; CHECK: cmp [[EXTRA_SHIFT]], #0
64 ; CHECK: orr r0, r0, r1, lsl [[REVERSE_SHIFT]]
65 ; CHECK: asrge [[HI_TMP]], r1, #31
66 ; CHECK: asrge r0, r1, [[EXTRA_SHIFT]]
67 ; CHECK: mov r1, [[HI_TMP]]
69 ; EXPAND:      push {[[REG:r[0-9]+]], lr}
70 ; EXPAND-NEXT: bl __aeabi_lasr
71 ; EXPAND-NEXT: pop {[[REG]], pc}
72   %res = ashr i64 %val, %amt
73   ret i64 %res