forked from OSchip/llvm-project
[ARM GlobalISel] Support G_SELECT for Thumb2
Same as arm mode, but slightly different opcodes. llvm-svn: 353938
This commit is contained in:
parent
318f990aee
commit
aa4118a873
|
@ -97,10 +97,15 @@ private:
|
|||
unsigned STORE8;
|
||||
unsigned LOAD8;
|
||||
|
||||
// Used for G_ICMP
|
||||
unsigned CMPrr;
|
||||
unsigned MOVi;
|
||||
unsigned MOVCCi;
|
||||
|
||||
// Used for G_SELECT
|
||||
unsigned CMPri;
|
||||
unsigned MOVCCr;
|
||||
|
||||
OpcodeCache(const ARMSubtarget &STI);
|
||||
} const Opcodes;
|
||||
|
||||
|
@ -292,6 +297,9 @@ ARMInstructionSelector::OpcodeCache::OpcodeCache(const ARMSubtarget &STI) {
|
|||
STORE_OPCODE(CMPrr, CMPrr);
|
||||
STORE_OPCODE(MOVi, MOVi);
|
||||
STORE_OPCODE(MOVCCi, MOVCCi);
|
||||
|
||||
STORE_OPCODE(CMPri, CMPri);
|
||||
STORE_OPCODE(MOVCCr, MOVCCr);
|
||||
#undef MAP_OPCODE
|
||||
}
|
||||
|
||||
|
@ -696,7 +704,7 @@ bool ARMInstructionSelector::selectSelect(MachineInstrBuilder &MIB,
|
|||
auto CondReg = MIB->getOperand(1).getReg();
|
||||
assert(validReg(MRI, CondReg, 1, ARM::GPRRegBankID) &&
|
||||
"Unsupported types for select operation");
|
||||
auto CmpI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::CMPri))
|
||||
auto CmpI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(Opcodes.CMPri))
|
||||
.addUse(CondReg)
|
||||
.addImm(0)
|
||||
.add(predOps(ARMCC::AL));
|
||||
|
@ -711,7 +719,7 @@ bool ARMInstructionSelector::selectSelect(MachineInstrBuilder &MIB,
|
|||
assert(validOpRegPair(MRI, ResReg, TrueReg, 32, ARM::GPRRegBankID) &&
|
||||
validOpRegPair(MRI, TrueReg, FalseReg, 32, ARM::GPRRegBankID) &&
|
||||
"Unsupported types for select operation");
|
||||
auto Mov1I = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::MOVCCr))
|
||||
auto Mov1I = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(Opcodes.MOVCCr))
|
||||
.addDef(ResReg)
|
||||
.addUse(TrueReg)
|
||||
.addUse(FalseReg)
|
||||
|
|
|
@ -124,6 +124,9 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
|
|||
.legalForCartesianProduct({s1}, {s32, p0})
|
||||
.minScalar(1, s32);
|
||||
|
||||
getActionDefinitionsBuilder(G_SELECT).legalForCartesianProduct({s32, p0},
|
||||
{s1});
|
||||
|
||||
// We're keeping these builders around because we'll want to add support for
|
||||
// floating point to them.
|
||||
auto &LoadStoreBuilder =
|
||||
|
@ -167,9 +170,6 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
|
|||
.clampScalar(0, s32, s32);
|
||||
}
|
||||
|
||||
getActionDefinitionsBuilder(G_SELECT).legalForCartesianProduct({s32, p0},
|
||||
{s1});
|
||||
|
||||
getActionDefinitionsBuilder(G_BRCOND).legalFor({s1});
|
||||
|
||||
// We're keeping these builders around because we'll want to add support for
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
# RUN: llc -mtriple arm-- -run-pass=legalizer %s -o - | FileCheck %s
|
||||
# RUN: llc -mtriple thumb-- -mattr=+v6t2 -run-pass=legalizer %s -o - | FileCheck %s
|
||||
--- |
|
||||
define void @test_select_s32() { ret void }
|
||||
define void @test_select_ptr() { ret void }
|
||||
...
|
||||
---
|
||||
name: test_select_s32
|
||||
# CHECK-LABEL: name: test_select_s32
|
||||
legalized: false
|
||||
# CHECK: legalized: true
|
||||
regBankSelected: false
|
||||
selected: false
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
- { id: 3, class: _ }
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $r0, $r1, $r2
|
||||
|
||||
%0(s32) = COPY $r0
|
||||
%1(s32) = COPY $r1
|
||||
%2(s1) = G_CONSTANT i1 1
|
||||
%3(s32) = G_SELECT %2(s1), %0, %1
|
||||
; G_SELECT with s32 is legal, so we should find it unchanged in the output
|
||||
; CHECK: {{%[0-9]+}}:_(s32) = G_SELECT {{%[0-9]+}}(s1), {{%[0-9]+}}, {{%[0-9]+}}
|
||||
$r0 = COPY %3(s32)
|
||||
BX_RET 14, $noreg, implicit $r0
|
||||
...
|
||||
---
|
||||
name: test_select_ptr
|
||||
# CHECK-LABEL: name: test_select_ptr
|
||||
legalized: false
|
||||
# CHECK: legalized: true
|
||||
regBankSelected: false
|
||||
selected: false
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
- { id: 3, class: _ }
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $r0, $r1, $r2
|
||||
|
||||
%0(p0) = COPY $r0
|
||||
%1(p0) = COPY $r1
|
||||
%2(s1) = G_CONSTANT i1 0
|
||||
%3(p0) = G_SELECT %2(s1), %0, %1
|
||||
; G_SELECT with p0 is legal, so we should find it unchanged in the output
|
||||
; CHECK: {{%[0-9]+}}:_(p0) = G_SELECT {{%[0-9]+}}(s1), {{%[0-9]+}}, {{%[0-9]+}}
|
||||
$r0 = COPY %3(p0)
|
||||
BX_RET 14, $noreg, implicit $r0
|
||||
...
|
|
@ -5,9 +5,6 @@
|
|||
|
||||
define void @test_constants_s64() { ret void }
|
||||
|
||||
define void @test_select_s32() { ret void }
|
||||
define void @test_select_ptr() { ret void }
|
||||
|
||||
define void @test_brcond() { ret void }
|
||||
|
||||
define void @test_phi_s32() { ret void }
|
||||
|
@ -108,58 +105,6 @@ body: |
|
|||
BX_RET 14, $noreg
|
||||
...
|
||||
---
|
||||
name: test_select_s32
|
||||
# CHECK-LABEL: name: test_select_s32
|
||||
legalized: false
|
||||
# CHECK: legalized: true
|
||||
regBankSelected: false
|
||||
selected: false
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
- { id: 3, class: _ }
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $r0, $r1, $r2
|
||||
|
||||
%0(s32) = COPY $r0
|
||||
%1(s32) = COPY $r1
|
||||
%2(s1) = G_CONSTANT i1 1
|
||||
%3(s32) = G_SELECT %2(s1), %0, %1
|
||||
; G_SELECT with s32 is legal, so we should find it unchanged in the output
|
||||
; CHECK: {{%[0-9]+}}:_(s32) = G_SELECT {{%[0-9]+}}(s1), {{%[0-9]+}}, {{%[0-9]+}}
|
||||
$r0 = COPY %3(s32)
|
||||
BX_RET 14, $noreg, implicit $r0
|
||||
...
|
||||
---
|
||||
name: test_select_ptr
|
||||
# CHECK-LABEL: name: test_select_ptr
|
||||
legalized: false
|
||||
# CHECK: legalized: true
|
||||
regBankSelected: false
|
||||
selected: false
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
- { id: 3, class: _ }
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $r0, $r1, $r2
|
||||
|
||||
%0(p0) = COPY $r0
|
||||
%1(p0) = COPY $r1
|
||||
%2(s1) = G_CONSTANT i1 0
|
||||
%3(p0) = G_SELECT %2(s1), %0, %1
|
||||
; G_SELECT with p0 is legal, so we should find it unchanged in the output
|
||||
; CHECK: {{%[0-9]+}}:_(p0) = G_SELECT {{%[0-9]+}}(s1), {{%[0-9]+}}, {{%[0-9]+}}
|
||||
$r0 = COPY %3(p0)
|
||||
BX_RET 14, $noreg, implicit $r0
|
||||
...
|
||||
---
|
||||
name: test_brcond
|
||||
# CHECK-LABEL: name: test_brcond
|
||||
legalized: false
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
# RUN: llc -O0 -mtriple thumb-- -mattr=+v6t2 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
|
||||
--- |
|
||||
define void @test_select_s32() { ret void }
|
||||
define void @test_select_ptr() { ret void }
|
||||
...
|
||||
---
|
||||
name: test_select_s32
|
||||
# CHECK-LABEL: name: test_select_s32
|
||||
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 }
|
||||
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(s1) = G_TRUNC %1(s32)
|
||||
; CHECK: [[VREGC:%[0-9]+]]:gprnopc = COPY [[VREGY]]
|
||||
|
||||
%3(s32) = G_SELECT %2(s1), %0, %1
|
||||
; CHECK: t2CMPri [[VREGC]], 0, 14, $noreg, implicit-def $cpsr
|
||||
; CHECK: [[RES:%[0-9]+]]:rgpr = t2MOVCCr [[VREGX]], [[VREGY]], 0, $cpsr
|
||||
|
||||
$r0 = COPY %3(s32)
|
||||
; CHECK: $r0 = COPY [[RES]]
|
||||
|
||||
BX_RET 14, $noreg, implicit $r0
|
||||
; CHECK: BX_RET 14, $noreg, implicit $r0
|
||||
...
|
||||
---
|
||||
name: test_select_ptr
|
||||
# CHECK-LABEL: name: test_select_ptr
|
||||
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 }
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $r0, $r1, $r2
|
||||
|
||||
%0(p0) = COPY $r0
|
||||
; CHECK: [[VREGX:%[0-9]+]]:rgpr = COPY $r0
|
||||
|
||||
%1(p0) = COPY $r1
|
||||
; CHECK: [[VREGY:%[0-9]+]]:rgpr = COPY $r1
|
||||
|
||||
%2(s32) = COPY $r2
|
||||
; CHECK: [[VREGC32:%[0-9]+]]:gpr = COPY $r2
|
||||
|
||||
%3(s1) = G_TRUNC %2(s32)
|
||||
; CHECK: [[VREGC:%[0-9]+]]:gprnopc = COPY [[VREGC32]]
|
||||
|
||||
%4(p0) = G_SELECT %3(s1), %0, %1
|
||||
; CHECK: t2CMPri [[VREGC]], 0, 14, $noreg, implicit-def $cpsr
|
||||
; CHECK: [[RES:%[0-9]+]]:rgpr = t2MOVCCr [[VREGX]], [[VREGY]], 0, $cpsr
|
||||
|
||||
$r0 = COPY %4(p0)
|
||||
; CHECK: $r0 = COPY [[RES]]
|
||||
|
||||
BX_RET 14, $noreg, implicit $r0
|
||||
; CHECK: BX_RET 14, $noreg, implicit $r0
|
||||
...
|
Loading…
Reference in New Issue