1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[ARM GlobalISel] Support shifts for Thumb2

Same as ARM.

On this occasion we split some of the instruction select tests for more
complicated instructions into their own files, so we can reuse them for
ARM and Thumb mode. Likewise for the legalizer tests.

llvm-svn: 352188
This commit is contained in:
Diana Picus 2019-01-25 10:48:42 +00:00
parent d574f09322
commit 3fa34396d2
7 changed files with 600 additions and 522 deletions

View File

@ -88,6 +88,10 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
.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}});
@ -135,10 +139,6 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
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})

View File

@ -7,11 +7,6 @@
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 }
@ -20,14 +15,6 @@
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 }
@ -223,186 +210,6 @@ body: |
; 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
@ -606,252 +413,6 @@ body: |
; 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

View File

@ -24,6 +24,10 @@
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
@ -559,3 +563,78 @@ body: |
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
...

View File

@ -1,9 +1,5 @@
# 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 }
@ -31,81 +27,6 @@
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

View File

@ -0,0 +1,275 @@
# 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
...

View File

@ -0,0 +1,147 @@
# 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
...

View File

@ -0,0 +1,95 @@
# 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
...