.legalFor({s32})
.minScalar(0, s32);
+ getActionDefinitionsBuilder({G_ASHR, G_LSHR, G_SHL})
+ .legalFor({{s32, s32}})
+ .clampScalar(1, s32, s32);
+
getActionDefinitionsBuilder(G_INTTOPTR).legalFor({{p0, s32}});
getActionDefinitionsBuilder(G_PTRTOINT).legalFor({{s32, p0}});
setAction({Op, s32}, Libcall);
}
- getActionDefinitionsBuilder({G_ASHR, G_LSHR, G_SHL})
- .legalFor({{s32, s32}})
- .clampScalar(1, s32, s32);
-
if (ST.hasV5TOps()) {
getActionDefinitionsBuilder(G_CTLZ)
.legalFor({s32})
define void @test_mls() #2 { ret void }
define void @test_no_mls() { ret void }
- define void @test_shifts_to_revsh() #0 { ret void }
- define void @test_shifts_to_revsh_commutative() #0 { ret void }
- define void @test_shifts_no_revsh_features() #1 { ret void }
- define void @test_shifts_no_revsh_constants() #0 { ret void }
-
define void @test_bicrr() { ret void }
define void @test_bicrr_commutative() { ret void }
define void @test_bicri_commutative_and() { ret void }
define void @test_bicri_commutative_both() { ret void }
- define void @test_pkhbt() #0 { ret void }
- define void @test_pkhbt_commutative() #0 { ret void }
- define void @test_pkhbt_imm16_31() #0 { ret void }
- define void @test_pkhbt_unshifted() #0 { ret void }
-
- define void @test_pkhtb_imm16() #0 { ret void }
- define void @test_pkhtb_imm1_15() #0 { ret void }
-
define void @test_movti16_0xffff() #2 { ret void }
define void @test_vnmuls() #3 { ret void }
; CHECK: BX_RET 14, $noreg, implicit $r0
...
---
-name: test_shifts_to_revsh
-# CHECK-LABEL: name: test_shifts_to_revsh
-legalized: true
-regBankSelected: true
-selected: false
-# CHECK: selected: true
-registers:
- - { id: 0, class: gprb }
- - { id: 1, class: gprb }
- - { id: 2, class: gprb }
- - { id: 3, class: gprb }
- - { id: 4, class: gprb }
- - { id: 5, class: gprb }
- - { id: 6, class: gprb }
- - { id: 7, class: gprb }
- - { id: 8, class: gprb }
- - { id: 9, class: gprb }
-body: |
- bb.0:
- liveins: $r0
-
- %0(s32) = COPY $r0
- ; CHECK: [[VREGX:%[0-9]+]]:gpr = COPY $r0
-
- %1(s32) = G_CONSTANT i32 24
- %2(s32) = G_SHL %0(s32), %1(s32)
-
- %3(s32) = G_CONSTANT i32 16
- %4(s32) = G_ASHR %2(s32), %3(s32)
-
- %5(s32) = G_CONSTANT i32 8
- %6(s32) = G_LSHR %0(s32), %5(s32)
-
- %7(s32) = G_CONSTANT 255
- %8(s32) = G_AND %6(s32), %7(s32)
-
- %9(s32) = G_OR %4(s32), %8(s32)
- ; CHECK: [[VREGR:%[0-9]+]]:gpr = REVSH [[VREGX]]
-
- $r0 = COPY %9(s32)
- ; CHECK: $r0 = COPY [[VREGR]]
-
- BX_RET 14, $noreg, implicit $r0
- ; CHECK: BX_RET 14, $noreg, implicit $r0
-...
----
-name: test_shifts_to_revsh_commutative
-# CHECK-LABEL: name: test_shifts_to_revsh_commutative
-legalized: true
-regBankSelected: true
-selected: false
-# CHECK: selected: true
-registers:
- - { id: 0, class: gprb }
- - { id: 1, class: gprb }
- - { id: 2, class: gprb }
- - { id: 3, class: gprb }
- - { id: 4, class: gprb }
- - { id: 5, class: gprb }
- - { id: 6, class: gprb }
- - { id: 7, class: gprb }
- - { id: 8, class: gprb }
- - { id: 9, class: gprb }
-body: |
- bb.0:
- liveins: $r0
-
- %0(s32) = COPY $r0
- ; CHECK: [[VREGX:%[0-9]+]]:gpr = COPY $r0
-
- %1(s32) = G_CONSTANT i32 24
- %2(s32) = G_SHL %0(s32), %1(s32)
-
- %3(s32) = G_CONSTANT i32 16
- %4(s32) = G_ASHR %2(s32), %3(s32)
-
- %5(s32) = G_CONSTANT i32 8
- %6(s32) = G_LSHR %0(s32), %5(s32)
-
- %7(s32) = G_CONSTANT 255
- %8(s32) = G_AND %6(s32), %7(s32)
-
- %9(s32) = G_OR %8(s32), %4(s32)
- ; CHECK: [[VREGR:%[0-9]+]]:gpr = REVSH [[VREGX]]
-
- $r0 = COPY %9(s32)
- ; CHECK: $r0 = COPY [[VREGR]]
-
- BX_RET 14, $noreg, implicit $r0
- ; CHECK: BX_RET 14, $noreg, implicit $r0
-...
----
-name: test_shifts_no_revsh_features
-# CHECK-LABEL: name: test_shifts_no_revsh
-legalized: true
-regBankSelected: true
-selected: false
-# CHECK: selected: true
-registers:
- - { id: 0, class: gprb }
- - { id: 1, class: gprb }
- - { id: 2, class: gprb }
- - { id: 3, class: gprb }
- - { id: 4, class: gprb }
- - { id: 5, class: gprb }
- - { id: 6, class: gprb }
- - { id: 7, class: gprb }
- - { id: 8, class: gprb }
- - { id: 9, class: gprb }
-body: |
- bb.0:
- liveins: $r0
-
- %0(s32) = COPY $r0
-
- %1(s32) = G_CONSTANT i32 24
- %2(s32) = G_SHL %0(s32), %1(s32)
-
- %3(s32) = G_CONSTANT i32 16
- %4(s32) = G_ASHR %2(s32), %3(s32)
-
- %5(s32) = G_CONSTANT i32 8
- %6(s32) = G_LSHR %0(s32), %5(s32)
-
- %7(s32) = G_CONSTANT 255
- %8(s32) = G_AND %6(s32), %7(s32)
-
- %9(s32) = G_OR %4(s32), %8(s32)
- ; We don't really care how this is folded as long as it's not into a REVSH.
- ; CHECK-NOT: REVSH
-
- $r0 = COPY %9(s32)
-
- BX_RET 14, $noreg, implicit $r0
-...
----
-name: test_shifts_no_revsh_constants
-# CHECK-LABEL: name: test_shifts_no_revsh_constants
-legalized: true
-regBankSelected: true
-selected: false
-# CHECK: selected: true
-registers:
- - { id: 0, class: gprb }
- - { id: 1, class: gprb }
- - { id: 2, class: gprb }
- - { id: 3, class: gprb }
- - { id: 4, class: gprb }
- - { id: 5, class: gprb }
- - { id: 6, class: gprb }
- - { id: 7, class: gprb }
- - { id: 8, class: gprb }
- - { id: 9, class: gprb }
-body: |
- bb.0:
- liveins: $r0
-
- %0(s32) = COPY $r0
-
- %1(s32) = G_CONSTANT i32 16 ; REVSH needs 24 here
- %2(s32) = G_SHL %0(s32), %1(s32)
-
- %3(s32) = G_CONSTANT i32 24 ; REVSH needs 16 here
- %4(s32) = G_ASHR %2(s32), %3(s32)
-
- %5(s32) = G_CONSTANT i32 8
- %6(s32) = G_LSHR %0(s32), %5(s32)
-
- %7(s32) = G_CONSTANT 255
- %8(s32) = G_AND %6(s32), %7(s32)
-
- %9(s32) = G_OR %4(s32), %8(s32)
- ; We don't really care how this is folded as long as it's not into a REVSH.
- ; CHECK-NOT: REVSH
-
- $r0 = COPY %9(s32)
-
- BX_RET 14, $noreg, implicit $r0
-...
----
name: test_bicrr
# CHECK-LABEL: name: test_bicrr
legalized: true
; CHECK: BX_RET 14, $noreg, implicit $r0
...
---
-name: test_pkhbt
-# CHECK-LABEL: name: test_pkhbt
-legalized: true
-regBankSelected: true
-selected: false
-# CHECK: selected: true
-registers:
- - { id: 0, class: gprb }
- - { id: 1, class: gprb }
- - { id: 2, class: gprb }
- - { id: 3, class: gprb }
- - { id: 4, class: gprb }
- - { id: 5, class: gprb }
- - { id: 6, class: gprb }
- - { id: 7, class: gprb }
- - { id: 8, class: gprb }
-body: |
- bb.0:
- liveins: $r0, $r1
-
- %0(s32) = COPY $r0
- %1(s32) = COPY $r1
- ; CHECK-DAG: [[VREGX:%[0-9]+]]:gprnopc = COPY $r0
- ; CHECK-DAG: [[VREGY:%[0-9]+]]:gprnopc = COPY $r1
-
- %2(s32) = G_CONSTANT i32 65535 ; 0xFFFF
- %3(s32) = G_AND %0, %2
-
- %4(s32) = G_CONSTANT i32 7
- %5(s32) = G_SHL %1, %4
- %6(s32) = G_CONSTANT i32 4294901760 ; 0xFFFF0000
- %7(s32) = G_AND %5, %6
-
- %8(s32) = G_OR %3, %7
- ; CHECK: [[VREGR:%[0-9]+]]:gprnopc = PKHBT [[VREGX]], [[VREGY]], 7, 14, $noreg
-
- $r0 = COPY %8(s32)
- ; CHECK: $r0 = COPY [[VREGR]]
-
- BX_RET 14, $noreg, implicit $r0
- ; CHECK: BX_RET 14, $noreg, implicit $r0
-...
----
-name: test_pkhbt_commutative
-# CHECK-LABEL: name: test_pkhbt_commutative
-legalized: true
-regBankSelected: true
-selected: false
-# CHECK: selected: true
-registers:
- - { id: 0, class: gprb }
- - { id: 1, class: gprb }
- - { id: 2, class: gprb }
- - { id: 3, class: gprb }
- - { id: 4, class: gprb }
- - { id: 5, class: gprb }
- - { id: 6, class: gprb }
- - { id: 7, class: gprb }
- - { id: 8, class: gprb }
-body: |
- bb.0:
- liveins: $r0, $r1
-
- %0(s32) = COPY $r0
- %1(s32) = COPY $r1
- ; CHECK-DAG: [[VREGX:%[0-9]+]]:gprnopc = COPY $r0
- ; CHECK-DAG: [[VREGY:%[0-9]+]]:gprnopc = COPY $r1
-
- %2(s32) = G_CONSTANT i32 65535 ; 0xFFFF
- %3(s32) = G_AND %0, %2
-
- %4(s32) = G_CONSTANT i32 7
- %5(s32) = G_SHL %1, %4
- %6(s32) = G_CONSTANT i32 4294901760 ; 0xFFFF0000
- %7(s32) = G_AND %5, %6
-
- %8(s32) = G_OR %7, %3
- ; CHECK: [[VREGR:%[0-9]+]]:gprnopc = PKHBT [[VREGX]], [[VREGY]], 7, 14, $noreg
-
- $r0 = COPY %8(s32)
- ; CHECK: $r0 = COPY [[VREGR]]
-
- BX_RET 14, $noreg, implicit $r0
- ; CHECK: BX_RET 14, $noreg, implicit $r0
-...
----
-name: test_pkhbt_imm16_31
-# CHECK-LABEL: name: test_pkhbt_imm16_31
-legalized: true
-regBankSelected: true
-selected: false
-# CHECK: selected: true
-registers:
- - { id: 0, class: gprb }
- - { id: 1, class: gprb }
- - { id: 2, class: gprb }
- - { id: 3, class: gprb }
- - { id: 4, class: gprb }
- - { id: 5, class: gprb }
- - { id: 6, class: gprb }
-body: |
- bb.0:
- liveins: $r0, $r1
-
- %0(s32) = COPY $r0
- %1(s32) = COPY $r1
- ; CHECK-DAG: [[VREGX:%[0-9]+]]:gprnopc = COPY $r0
- ; CHECK-DAG: [[VREGY:%[0-9]+]]:gprnopc = COPY $r1
-
- %2(s32) = G_CONSTANT i32 65535 ; 0xFFFF
- %3(s32) = G_AND %0, %2
-
- %4(s32) = G_CONSTANT i32 17
- %5(s32) = G_SHL %1, %4
-
- %6(s32) = G_OR %3, %5
- ; CHECK: [[VREGR:%[0-9]+]]:gprnopc = PKHBT [[VREGX]], [[VREGY]], 17, 14, $noreg
-
- $r0 = COPY %6(s32)
- ; CHECK: $r0 = COPY [[VREGR]]
-
- BX_RET 14, $noreg, implicit $r0
- ; CHECK: BX_RET 14, $noreg, implicit $r0
-...
----
-name: test_pkhbt_unshifted
-# CHECK-LABEL: name: test_pkhbt_unshifted
-legalized: true
-regBankSelected: true
-selected: false
-# CHECK: selected: true
-registers:
- - { id: 0, class: gprb }
- - { id: 1, class: gprb }
- - { id: 2, class: gprb }
- - { id: 3, class: gprb }
- - { id: 4, class: gprb }
- - { id: 5, class: gprb }
- - { id: 6, class: gprb }
-body: |
- bb.0:
- liveins: $r0, $r1
-
- %0(s32) = COPY $r0
- %1(s32) = COPY $r1
- ; CHECK-DAG: [[VREGX:%[0-9]+]]:gprnopc = COPY $r0
- ; CHECK-DAG: [[VREGY:%[0-9]+]]:gprnopc = COPY $r1
-
- %2(s32) = G_CONSTANT i32 65535 ; 0xFFFF
- %3(s32) = G_AND %0, %2
-
- %4(s32) = G_CONSTANT i32 4294901760 ; 0xFFFF0000
- %5(s32) = G_AND %1, %4
-
- %6(s32) = G_OR %3, %5
- ; CHECK: [[VREGR:%[0-9]+]]:gprnopc = PKHBT [[VREGX]], [[VREGY]], 0, 14, $noreg
-
- $r0 = COPY %6(s32)
- ; CHECK: $r0 = COPY [[VREGR]]
-
- BX_RET 14, $noreg, implicit $r0
- ; CHECK: BX_RET 14, $noreg, implicit $r0
-...
----
-name: test_pkhtb_imm16
-# CHECK-LABEL: name: test_pkhtb_imm16
-legalized: true
-regBankSelected: true
-selected: false
-# CHECK: selected: true
-registers:
- - { id: 0, class: gprb }
- - { id: 1, class: gprb }
- - { id: 2, class: gprb }
- - { id: 3, class: gprb }
- - { id: 4, class: gprb }
- - { id: 5, class: gprb }
- - { id: 6, class: gprb }
-body: |
- bb.0:
- liveins: $r0, $r1
-
- %0(s32) = COPY $r0
- %1(s32) = COPY $r1
- ; CHECK-DAG: [[VREGX:%[0-9]+]]:gprnopc = COPY $r0
- ; CHECK-DAG: [[VREGY:%[0-9]+]]:gprnopc = COPY $r1
-
- %2(s32) = G_CONSTANT i32 4294901760 ; 0xFFFF0000
- %3(s32) = G_AND %0, %2
-
- %4(s32) = G_CONSTANT i32 16
- %5(s32) = G_LSHR %1, %4
-
- %6(s32) = G_OR %3, %5
- ; CHECK: [[VREGR:%[0-9]+]]:gprnopc = PKHTB [[VREGX]], [[VREGY]], 16, 14, $noreg
-
- $r0 = COPY %6(s32)
- ; CHECK: $r0 = COPY [[VREGR]]
-
- BX_RET 14, $noreg, implicit $r0
- ; CHECK: BX_RET 14, $noreg, implicit $r0
-...
----
-name: test_pkhtb_imm1_15
-# CHECK-LABEL: name: test_pkhtb_imm1_15
-legalized: true
-regBankSelected: true
-selected: false
-# CHECK: selected: true
-registers:
- - { id: 0, class: gprb }
- - { id: 1, class: gprb }
- - { id: 2, class: gprb }
- - { id: 3, class: gprb }
- - { id: 4, class: gprb }
- - { id: 5, class: gprb }
- - { id: 6, class: gprb }
- - { id: 7, class: gprb }
- - { id: 8, class: gprb }
-body: |
- bb.0:
- liveins: $r0, $r1
-
- %0(s32) = COPY $r0
- %1(s32) = COPY $r1
- ; CHECK-DAG: [[VREGX:%[0-9]+]]:gprnopc = COPY $r0
- ; CHECK-DAG: [[VREGY:%[0-9]+]]:gprnopc = COPY $r1
-
- %2(s32) = G_CONSTANT i32 4294901760 ; 0xFFFF0000
- %3(s32) = G_AND %0, %2
-
- %4(s32) = G_CONSTANT i32 7
- %5(s32) = G_LSHR %1, %4
- %6(s32) = G_CONSTANT i32 65535 ; 0xFFFF
- %7(s32) = G_AND %5, %6
-
- %8(s32) = G_OR %3, %7
- ; CHECK: [[VREGR:%[0-9]+]]:gprnopc = PKHTB [[VREGX]], [[VREGY]], 7, 14, $noreg
-
- $r0 = COPY %8(s32)
- ; CHECK: $r0 = COPY [[VREGR]]
-
- BX_RET 14, $noreg, implicit $r0
- ; CHECK: BX_RET 14, $noreg, implicit $r0
-...
----
name: test_movti16_0xffff
# CHECK-LABEL: name: test_movti16_0xffff
legalized: true
define void @test_xor_s8() { ret void }
define void @test_xor_s16() { ret void }
define void @test_xor_s32() { ret void }
+
+ define void @test_lshr_s32() { ret void }
+ define void @test_ashr_s32() { ret void }
+ define void @test_shl_s32() { ret void }
...
---
name: test_add_s8
BX_RET 14, $noreg, implicit $r0
...
+---
+name: test_lshr_s32
+# CHECK-LABEL: name: test_lshr_s32
+legalized: false
+# CHECK: legalized: true
+regBankSelected: false
+selected: false
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+body: |
+ bb.0:
+ liveins: $r0, $r1
+
+ %0(s32) = COPY $r0
+ %1(s32) = COPY $r1
+ %2(s32) = G_LSHR %0, %1
+ ; G_LSHR with s32 is legal, so we should find it unchanged in the output
+ ; CHECK: {{%[0-9]+}}:_(s32) = G_LSHR {{%[0-9]+, %[0-9]+}}
+ $r0 = COPY %2(s32)
+ BX_RET 14, $noreg, implicit $r0
+
+...
+---
+name: test_ashr_s32
+# CHECK-LABEL: name: test_ashr_s32
+legalized: false
+# CHECK: legalized: true
+regBankSelected: false
+selected: false
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+body: |
+ bb.0:
+ liveins: $r0, $r1
+
+ %0(s32) = COPY $r0
+ %1(s32) = COPY $r1
+ %2(s32) = G_ASHR %0, %1
+ ; G_ASHR with s32 is legal, so we should find it unchanged in the output
+ ; CHECK: {{%[0-9]+}}:_(s32) = G_ASHR {{%[0-9]+, %[0-9]+}}
+ $r0 = COPY %2(s32)
+ BX_RET 14, $noreg, implicit $r0
+
+...
+---
+name: test_shl_s32
+# CHECK-LABEL: name: test_shl_s32
+legalized: false
+# CHECK: legalized: true
+regBankSelected: false
+selected: false
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+body: |
+ bb.0:
+ liveins: $r0, $r1
+
+ %0(s32) = COPY $r0
+ %1(s32) = COPY $r1
+ %2(s32) = G_SHL %0, %1
+ ; G_SHL with s32 is legal, so we should find it unchanged in the output
+ ; CHECK: {{%[0-9]+}}:_(s32) = G_SHL {{%[0-9]+, %[0-9]+}}
+ $r0 = COPY %2(s32)
+ BX_RET 14, $noreg, implicit $r0
+
+...
# RUN: llc -mtriple arm-- -run-pass=legalizer %s -o - | FileCheck %s
--- |
- define void @test_lshr_s32() { ret void }
- define void @test_ashr_s32() { ret void }
- define void @test_shl_s32() { ret void }
-
define void @test_load_from_stack() { ret void }
define void @test_load_store_64() #0 { ret void }
attributes #0 = { "target-features"="+vfp2" }
...
---
-name: test_lshr_s32
-# CHECK-LABEL: name: test_lshr_s32
-legalized: false
-# CHECK: legalized: true
-regBankSelected: false
-selected: false
-tracksRegLiveness: true
-registers:
- - { id: 0, class: _ }
- - { id: 1, class: _ }
- - { id: 2, class: _ }
-body: |
- bb.0:
- liveins: $r0, $r1
-
- %0(s32) = COPY $r0
- %1(s32) = COPY $r1
- %2(s32) = G_LSHR %0, %1
- ; G_LSHR with s32 is legal, so we should find it unchanged in the output
- ; CHECK: {{%[0-9]+}}:_(s32) = G_LSHR {{%[0-9]+, %[0-9]+}}
- $r0 = COPY %2(s32)
- BX_RET 14, $noreg, implicit $r0
-
-...
----
-name: test_ashr_s32
-# CHECK-LABEL: name: test_ashr_s32
-legalized: false
-# CHECK: legalized: true
-regBankSelected: false
-selected: false
-tracksRegLiveness: true
-registers:
- - { id: 0, class: _ }
- - { id: 1, class: _ }
- - { id: 2, class: _ }
-body: |
- bb.0:
- liveins: $r0, $r1
-
- %0(s32) = COPY $r0
- %1(s32) = COPY $r1
- %2(s32) = G_ASHR %0, %1
- ; G_ASHR with s32 is legal, so we should find it unchanged in the output
- ; CHECK: {{%[0-9]+}}:_(s32) = G_ASHR {{%[0-9]+, %[0-9]+}}
- $r0 = COPY %2(s32)
- BX_RET 14, $noreg, implicit $r0
-
-...
----
-name: test_shl_s32
-# CHECK-LABEL: name: test_shl_s32
-legalized: false
-# CHECK: legalized: true
-regBankSelected: false
-selected: false
-tracksRegLiveness: true
-registers:
- - { id: 0, class: _ }
- - { id: 1, class: _ }
- - { id: 2, class: _ }
-body: |
- bb.0:
- liveins: $r0, $r1
-
- %0(s32) = COPY $r0
- %1(s32) = COPY $r1
- %2(s32) = G_SHL %0, %1
- ; G_SHL with s32 is legal, so we should find it unchanged in the output
- ; CHECK: {{%[0-9]+}}:_(s32) = G_SHL {{%[0-9]+, %[0-9]+}}
- $r0 = COPY %2(s32)
- BX_RET 14, $noreg, implicit $r0
-
-...
----
name: test_load_from_stack
# CHECK-LABEL: name: test_load_from_stack
legalized: false
--- /dev/null
+# RUN: llc -O0 -mtriple arm-- -mattr=+v6 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,ARM
+# RUN: llc -O0 -mtriple thumb-- -mattr=+v6t2,+dsp -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,THUMB
+--- |
+ define void @test_pkhbt() { ret void }
+ define void @test_pkhbt_commutative() { ret void }
+ define void @test_pkhbt_imm16_31() { ret void }
+ define void @test_pkhbt_unshifted() { ret void }
+
+ define void @test_pkhtb_imm16() { ret void }
+ define void @test_pkhtb_imm1_15() { ret void }
+...
+---
+name: test_pkhbt
+# CHECK-LABEL: name: test_pkhbt
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: gprb }
+ - { id: 2, class: gprb }
+ - { id: 3, class: gprb }
+ - { id: 4, class: gprb }
+ - { id: 5, class: gprb }
+ - { id: 6, class: gprb }
+ - { id: 7, class: gprb }
+ - { id: 8, class: gprb }
+body: |
+ bb.0:
+ liveins: $r0, $r1
+
+ %0(s32) = COPY $r0
+ %1(s32) = COPY $r1
+ ; ARM-DAG: [[VREGX:%[0-9]+]]:gprnopc = COPY $r0
+ ; ARM-DAG: [[VREGY:%[0-9]+]]:gprnopc = COPY $r1
+ ; THUMB-DAG: [[VREGX:%[0-9]+]]:rgpr = COPY $r0
+ ; THUMB-DAG: [[VREGY:%[0-9]+]]:rgpr = COPY $r1
+
+ %2(s32) = G_CONSTANT i32 65535 ; 0xFFFF
+ %3(s32) = G_AND %0, %2
+
+ %4(s32) = G_CONSTANT i32 7
+ %5(s32) = G_SHL %1, %4
+ %6(s32) = G_CONSTANT i32 4294901760 ; 0xFFFF0000
+ %7(s32) = G_AND %5, %6
+
+ %8(s32) = G_OR %3, %7
+ ; ARM: [[VREGR:%[0-9]+]]:gprnopc = PKHBT [[VREGX]], [[VREGY]], 7, 14, $noreg
+ ; THUMB: [[VREGR:%[0-9]+]]:rgpr = t2PKHBT [[VREGX]], [[VREGY]], 7, 14, $noreg
+
+ $r0 = COPY %8(s32)
+ ; CHECK: $r0 = COPY [[VREGR]]
+
+ BX_RET 14, $noreg, implicit $r0
+ ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name: test_pkhbt_commutative
+# CHECK-LABEL: name: test_pkhbt_commutative
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: gprb }
+ - { id: 2, class: gprb }
+ - { id: 3, class: gprb }
+ - { id: 4, class: gprb }
+ - { id: 5, class: gprb }
+ - { id: 6, class: gprb }
+ - { id: 7, class: gprb }
+ - { id: 8, class: gprb }
+body: |
+ bb.0:
+ liveins: $r0, $r1
+
+ %0(s32) = COPY $r0
+ %1(s32) = COPY $r1
+ ; ARM-DAG: [[VREGX:%[0-9]+]]:gprnopc = COPY $r0
+ ; ARM-DAG: [[VREGY:%[0-9]+]]:gprnopc = COPY $r1
+ ; THUMB-DAG: [[VREGX:%[0-9]+]]:rgpr = COPY $r0
+ ; THUMB-DAG: [[VREGY:%[0-9]+]]:rgpr = COPY $r1
+
+ %2(s32) = G_CONSTANT i32 65535 ; 0xFFFF
+ %3(s32) = G_AND %0, %2
+
+ %4(s32) = G_CONSTANT i32 7
+ %5(s32) = G_SHL %1, %4
+ %6(s32) = G_CONSTANT i32 4294901760 ; 0xFFFF0000
+ %7(s32) = G_AND %5, %6
+
+ %8(s32) = G_OR %7, %3
+ ; ARM: [[VREGR:%[0-9]+]]:gprnopc = PKHBT [[VREGX]], [[VREGY]], 7, 14, $noreg
+ ; THUMB: [[VREGR:%[0-9]+]]:rgpr = t2PKHBT [[VREGX]], [[VREGY]], 7, 14, $noreg
+
+ $r0 = COPY %8(s32)
+ ; CHECK: $r0 = COPY [[VREGR]]
+
+ BX_RET 14, $noreg, implicit $r0
+ ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name: test_pkhbt_imm16_31
+# CHECK-LABEL: name: test_pkhbt_imm16_31
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: gprb }
+ - { id: 2, class: gprb }
+ - { id: 3, class: gprb }
+ - { id: 4, class: gprb }
+ - { id: 5, class: gprb }
+ - { id: 6, class: gprb }
+body: |
+ bb.0:
+ liveins: $r0, $r1
+
+ %0(s32) = COPY $r0
+ %1(s32) = COPY $r1
+ ; ARM-DAG: [[VREGX:%[0-9]+]]:gprnopc = COPY $r0
+ ; ARM-DAG: [[VREGY:%[0-9]+]]:gprnopc = COPY $r1
+ ; THUMB-DAG: [[VREGX:%[0-9]+]]:rgpr = COPY $r0
+ ; THUMB-DAG: [[VREGY:%[0-9]+]]:rgpr = COPY $r1
+
+ %2(s32) = G_CONSTANT i32 65535 ; 0xFFFF
+ %3(s32) = G_AND %0, %2
+
+ %4(s32) = G_CONSTANT i32 17
+ %5(s32) = G_SHL %1, %4
+
+ %6(s32) = G_OR %3, %5
+ ; ARM: [[VREGR:%[0-9]+]]:gprnopc = PKHBT [[VREGX]], [[VREGY]], 17, 14, $noreg
+ ; THUMB: [[VREGR:%[0-9]+]]:rgpr = t2PKHBT [[VREGX]], [[VREGY]], 17, 14, $noreg
+
+ $r0 = COPY %6(s32)
+ ; CHECK: $r0 = COPY [[VREGR]]
+
+ BX_RET 14, $noreg, implicit $r0
+ ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name: test_pkhbt_unshifted
+# CHECK-LABEL: name: test_pkhbt_unshifted
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: gprb }
+ - { id: 2, class: gprb }
+ - { id: 3, class: gprb }
+ - { id: 4, class: gprb }
+ - { id: 5, class: gprb }
+ - { id: 6, class: gprb }
+body: |
+ bb.0:
+ liveins: $r0, $r1
+
+ %0(s32) = COPY $r0
+ %1(s32) = COPY $r1
+ ; ARM-DAG: [[VREGX:%[0-9]+]]:gprnopc = COPY $r0
+ ; ARM-DAG: [[VREGY:%[0-9]+]]:gprnopc = COPY $r1
+ ; THUMB-DAG: [[VREGX:%[0-9]+]]:rgpr = COPY $r0
+ ; THUMB-DAG: [[VREGY:%[0-9]+]]:rgpr = COPY $r1
+
+ %2(s32) = G_CONSTANT i32 65535 ; 0xFFFF
+ %3(s32) = G_AND %0, %2
+
+ %4(s32) = G_CONSTANT i32 4294901760 ; 0xFFFF0000
+ %5(s32) = G_AND %1, %4
+
+ %6(s32) = G_OR %3, %5
+ ; ARM: [[VREGR:%[0-9]+]]:gprnopc = PKHBT [[VREGX]], [[VREGY]], 0, 14, $noreg
+ ; THUMB: [[VREGR:%[0-9]+]]:rgpr = t2PKHBT [[VREGX]], [[VREGY]], 0, 14, $noreg
+
+ $r0 = COPY %6(s32)
+ ; CHECK: $r0 = COPY [[VREGR]]
+
+ BX_RET 14, $noreg, implicit $r0
+ ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name: test_pkhtb_imm16
+# CHECK-LABEL: name: test_pkhtb_imm16
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: gprb }
+ - { id: 2, class: gprb }
+ - { id: 3, class: gprb }
+ - { id: 4, class: gprb }
+ - { id: 5, class: gprb }
+ - { id: 6, class: gprb }
+body: |
+ bb.0:
+ liveins: $r0, $r1
+
+ %0(s32) = COPY $r0
+ %1(s32) = COPY $r1
+ ; ARM-DAG: [[VREGX:%[0-9]+]]:gprnopc = COPY $r0
+ ; ARM-DAG: [[VREGY:%[0-9]+]]:gprnopc = COPY $r1
+ ; THUMB-DAG: [[VREGX:%[0-9]+]]:rgpr = COPY $r0
+ ; THUMB-DAG: [[VREGY:%[0-9]+]]:rgpr = COPY $r1
+
+ %2(s32) = G_CONSTANT i32 4294901760 ; 0xFFFF0000
+ %3(s32) = G_AND %0, %2
+
+ %4(s32) = G_CONSTANT i32 16
+ %5(s32) = G_LSHR %1, %4
+
+ %6(s32) = G_OR %3, %5
+ ; ARM: [[VREGR:%[0-9]+]]:gprnopc = PKHTB [[VREGX]], [[VREGY]], 16, 14, $noreg
+ ; THUMB: [[VREGR:%[0-9]+]]:rgpr = t2PKHTB [[VREGX]], [[VREGY]], 16, 14, $noreg
+
+ $r0 = COPY %6(s32)
+ ; CHECK: $r0 = COPY [[VREGR]]
+
+ BX_RET 14, $noreg, implicit $r0
+ ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name: test_pkhtb_imm1_15
+# CHECK-LABEL: name: test_pkhtb_imm1_15
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: gprb }
+ - { id: 2, class: gprb }
+ - { id: 3, class: gprb }
+ - { id: 4, class: gprb }
+ - { id: 5, class: gprb }
+ - { id: 6, class: gprb }
+ - { id: 7, class: gprb }
+ - { id: 8, class: gprb }
+body: |
+ bb.0:
+ liveins: $r0, $r1
+
+ %0(s32) = COPY $r0
+ %1(s32) = COPY $r1
+ ; ARM-DAG: [[VREGX:%[0-9]+]]:gprnopc = COPY $r0
+ ; ARM-DAG: [[VREGY:%[0-9]+]]:gprnopc = COPY $r1
+ ; THUMB-DAG: [[VREGX:%[0-9]+]]:rgpr = COPY $r0
+ ; THUMB-DAG: [[VREGY:%[0-9]+]]:rgpr = COPY $r1
+
+ %2(s32) = G_CONSTANT i32 4294901760 ; 0xFFFF0000
+ %3(s32) = G_AND %0, %2
+
+ %4(s32) = G_CONSTANT i32 7
+ %5(s32) = G_LSHR %1, %4
+ %6(s32) = G_CONSTANT i32 65535 ; 0xFFFF
+ %7(s32) = G_AND %5, %6
+
+ %8(s32) = G_OR %3, %7
+ ; ARM: [[VREGR:%[0-9]+]]:gprnopc = PKHTB [[VREGX]], [[VREGY]], 7, 14, $noreg
+ ; THUMB: [[VREGR:%[0-9]+]]:rgpr = t2PKHTB [[VREGX]], [[VREGY]], 7, 14, $noreg
+
+ $r0 = COPY %8(s32)
+ ; CHECK: $r0 = COPY [[VREGR]]
+
+ BX_RET 14, $noreg, implicit $r0
+ ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
--- /dev/null
+# RUN: llc -O0 -mtriple arm-- -mattr=+v6 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,ARM
+# RUN: llc -O0 -mtriple thumb-- -mattr=+v6t2 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,THUMB
+--- |
+ define void @test_shifts_to_revsh() { ret void }
+ define void @test_shifts_to_revsh_commutative() { ret void }
+ define void @test_shifts_no_revsh_constants() { ret void }
+...
+---
+name: test_shifts_to_revsh
+# CHECK-LABEL: name: test_shifts_to_revsh
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: gprb }
+ - { id: 2, class: gprb }
+ - { id: 3, class: gprb }
+ - { id: 4, class: gprb }
+ - { id: 5, class: gprb }
+ - { id: 6, class: gprb }
+ - { id: 7, class: gprb }
+ - { id: 8, class: gprb }
+ - { id: 9, class: gprb }
+body: |
+ bb.0:
+ liveins: $r0
+
+ %0(s32) = COPY $r0
+ ; ARM: [[VREGX:%[0-9]+]]:gpr = COPY $r0
+ ; THUMB: [[VREGX:%[0-9]+]]:rgpr = COPY $r0
+
+ %1(s32) = G_CONSTANT i32 24
+ %2(s32) = G_SHL %0(s32), %1(s32)
+
+ %3(s32) = G_CONSTANT i32 16
+ %4(s32) = G_ASHR %2(s32), %3(s32)
+
+ %5(s32) = G_CONSTANT i32 8
+ %6(s32) = G_LSHR %0(s32), %5(s32)
+
+ %7(s32) = G_CONSTANT 255
+ %8(s32) = G_AND %6(s32), %7(s32)
+
+ %9(s32) = G_OR %4(s32), %8(s32)
+ ; ARM: [[VREGR:%[0-9]+]]:gpr = REVSH [[VREGX]]
+ ; THUMB: [[VREGR:%[0-9]+]]:rgpr = t2REVSH [[VREGX]]
+
+ $r0 = COPY %9(s32)
+ ; CHECK: $r0 = COPY [[VREGR]]
+
+ BX_RET 14, $noreg, implicit $r0
+ ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name: test_shifts_to_revsh_commutative
+# CHECK-LABEL: name: test_shifts_to_revsh_commutative
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: gprb }
+ - { id: 2, class: gprb }
+ - { id: 3, class: gprb }
+ - { id: 4, class: gprb }
+ - { id: 5, class: gprb }
+ - { id: 6, class: gprb }
+ - { id: 7, class: gprb }
+ - { id: 8, class: gprb }
+ - { id: 9, class: gprb }
+body: |
+ bb.0:
+ liveins: $r0
+
+ %0(s32) = COPY $r0
+ ; ARM: [[VREGX:%[0-9]+]]:gpr = COPY $r0
+ ; THUMB: [[VREGX:%[0-9]+]]:rgpr = COPY $r0
+
+ %1(s32) = G_CONSTANT i32 24
+ %2(s32) = G_SHL %0(s32), %1(s32)
+
+ %3(s32) = G_CONSTANT i32 16
+ %4(s32) = G_ASHR %2(s32), %3(s32)
+
+ %5(s32) = G_CONSTANT i32 8
+ %6(s32) = G_LSHR %0(s32), %5(s32)
+
+ %7(s32) = G_CONSTANT 255
+ %8(s32) = G_AND %6(s32), %7(s32)
+
+ %9(s32) = G_OR %8(s32), %4(s32)
+ ; ARM: [[VREGR:%[0-9]+]]:gpr = REVSH [[VREGX]]
+ ; THUMB: [[VREGR:%[0-9]+]]:rgpr = t2REVSH [[VREGX]]
+
+ $r0 = COPY %9(s32)
+ ; CHECK: $r0 = COPY [[VREGR]]
+
+ BX_RET 14, $noreg, implicit $r0
+ ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name: test_shifts_no_revsh_constants
+# CHECK-LABEL: name: test_shifts_no_revsh_constants
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: gprb }
+ - { id: 2, class: gprb }
+ - { id: 3, class: gprb }
+ - { id: 4, class: gprb }
+ - { id: 5, class: gprb }
+ - { id: 6, class: gprb }
+ - { id: 7, class: gprb }
+ - { id: 8, class: gprb }
+ - { id: 9, class: gprb }
+body: |
+ bb.0:
+ liveins: $r0
+
+ %0(s32) = COPY $r0
+
+ %1(s32) = G_CONSTANT i32 16 ; REVSH needs 24 here
+ %2(s32) = G_SHL %0(s32), %1(s32)
+
+ %3(s32) = G_CONSTANT i32 24 ; REVSH needs 16 here
+ %4(s32) = G_ASHR %2(s32), %3(s32)
+
+ %5(s32) = G_CONSTANT i32 8
+ %6(s32) = G_LSHR %0(s32), %5(s32)
+
+ %7(s32) = G_CONSTANT 255
+ %8(s32) = G_AND %6(s32), %7(s32)
+
+ %9(s32) = G_OR %4(s32), %8(s32)
+ ; We don't really care how this is folded as long as it's not into a REVSH.
+ ; CHECK-NOT: REVSH
+
+ $r0 = COPY %9(s32)
+
+ BX_RET 14, $noreg, implicit $r0
+...
--- /dev/null
+# RUN: llc -O0 -mtriple thumb-- -mattr=+v6t2 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
+--- |
+ define void @test_ashr_rr() { ret void }
+
+ define void @test_shl_ri() { ret void }
+ define void @test_shl_ri_bad_imm() { ret void }
+...
+---
+name: test_ashr_rr
+# CHECK-LABEL: name: test_ashr_rr
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: gprb }
+ - { id: 2, class: gprb }
+body: |
+ bb.0:
+ liveins: $r0, $r1
+
+ %0(s32) = COPY $r0
+ ; CHECK: [[VREGX:%[0-9]+]]:rgpr = COPY $r0
+
+ %1(s32) = COPY $r1
+ ; CHECK: [[VREGY:%[0-9]+]]:rgpr = COPY $r1
+
+ %2(s32) = G_ASHR %0, %1
+ ; CHECK: [[VREGRES:%[0-9]+]]:rgpr = t2ASRrr [[VREGX]], [[VREGY]], 14, $noreg, $noreg
+
+ $r0 = COPY %2(s32)
+ ; CHECK: $r0 = COPY [[VREGRES]]
+
+ BX_RET 14, $noreg, implicit $r0
+ ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name: test_shl_ri
+# CHECK-LABEL: name: test_shl_ri
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: gprb }
+ - { id: 2, class: gprb }
+body: |
+ bb.0:
+ liveins: $r0
+
+ %0(s32) = COPY $r0
+ ; CHECK: [[VREGX:%[0-9]+]]:rgpr = COPY $r0
+
+ %1(s32) = G_CONSTANT i32 31
+ %2(s32) = G_SHL %0, %1
+ ; CHECK: [[VREGRES:%[0-9]+]]:rgpr = t2LSLri [[VREGX]], 31, 14, $noreg, $noreg
+
+ $r0 = COPY %2(s32)
+ ; CHECK: $r0 = COPY [[VREGRES]]
+
+ BX_RET 14, $noreg, implicit $r0
+ ; CHECK: BX_RET 14, $noreg, implicit $r0
+...
+---
+name: test_shl_ri_bad_imm
+# CHECK-LABEL: name: test_shl_ri_bad_imm
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: gprb }
+ - { id: 2, class: gprb }
+body: |
+ bb.0:
+ liveins: $r0
+
+ %0(s32) = COPY $r0
+ ; CHECK: [[VREGX:%[0-9]+]]:rgpr = COPY $r0
+
+ %1(s32) = G_CONSTANT i32 32
+ ; CHECK: [[VREGY:%[0-9]+]]:rgpr = t2MOVi 32, 14, $noreg, $noreg
+
+ %2(s32) = G_SHL %0, %1
+ ; CHECK: [[VREGRES:%[0-9]+]]:rgpr = t2LSLrr [[VREGX]], [[VREGY]], 14, $noreg, $noreg
+
+ $r0 = COPY %2(s32)
+ ; CHECK: $r0 = COPY [[VREGRES]]
+
+ BX_RET 14, $noreg, implicit $r0
+ ; CHECK: BX_RET 14, $noreg, implicit $r0
+...