mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-20 19:42:54 +02:00
[ARM] GlobalISel: Support G_BRCOND
Insert a TSTri to set the flags and a Bcc to branch based on their values. This is a bit inefficient in the (common) cases where the condition for the branch comes from a compare right before the branch, since we set the flags both as part of the compare lowering and as part of the branch lowering. We're going to live with that until we settle on a principled way to handle this kind of situation, which occurs with other patterns as well (combines might be the way forward here). llvm-svn: 308009
This commit is contained in:
parent
b597a7a7fd
commit
b4ef650c0e
@ -722,6 +722,29 @@ bool ARMInstructionSelector::select(MachineInstr &I) const {
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case G_BRCOND: {
|
||||
if (!validReg(MRI, I.getOperand(0).getReg(), 1, ARM::GPRRegBankID)) {
|
||||
DEBUG(dbgs() << "Unsupported condition register for G_BRCOND");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the flags.
|
||||
auto Test = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(ARM::TSTri))
|
||||
.addReg(I.getOperand(0).getReg())
|
||||
.addImm(1)
|
||||
.add(predOps(ARMCC::AL));
|
||||
if (!constrainSelectedInstRegOperands(*Test, TII, TRI, RBI))
|
||||
return false;
|
||||
|
||||
// Branch conditionally.
|
||||
auto Branch = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(ARM::Bcc))
|
||||
.add(I.getOperand(1))
|
||||
.add(predOps(ARMCC::EQ, ARM::CPSR));
|
||||
if (!constrainSelectedInstRegOperands(*Branch, TII, TRI, RBI))
|
||||
return false;
|
||||
I.eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -88,6 +88,8 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
|
||||
setAction({G_SELECT, p0}, Legal);
|
||||
setAction({G_SELECT, 1, s1}, Legal);
|
||||
|
||||
setAction({G_BRCOND, s1}, Legal);
|
||||
|
||||
setAction({G_CONSTANT, s32}, Legal);
|
||||
for (auto Ty : {s1, s8, s16})
|
||||
setAction({G_CONSTANT, Ty}, WidenScalar);
|
||||
|
@ -334,6 +334,10 @@ ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
case G_BR:
|
||||
OperandsMapping = getOperandsMapping({nullptr});
|
||||
break;
|
||||
case G_BRCOND:
|
||||
OperandsMapping =
|
||||
getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr});
|
||||
break;
|
||||
default:
|
||||
return getInvalidInstructionMapping();
|
||||
}
|
||||
|
@ -1181,17 +1181,35 @@ legalized: true
|
||||
regBankSelected: true
|
||||
selected: false
|
||||
# CHECK: selected: true
|
||||
registers:
|
||||
- { id: 0, class: gprb }
|
||||
body: |
|
||||
; CHECK: bb.0
|
||||
bb.0:
|
||||
successors: %bb.1(0x80000000)
|
||||
; CHECK: bb.0
|
||||
successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
||||
liveins: %r0
|
||||
|
||||
%0(s1) = COPY %r0
|
||||
; CHECK: [[COND:%[0-9]+]] = COPY %r0
|
||||
|
||||
G_BRCOND %0(s1), %bb.1
|
||||
; CHECK: TSTri [[COND]], 1, 14, _, implicit-def %cpsr
|
||||
; CHECK: Bcc %bb.1, 0, %cpsr
|
||||
G_BR %bb.2
|
||||
; CHECK: B %bb.2
|
||||
|
||||
; CHECK: bb.1
|
||||
bb.1:
|
||||
successors: %bb.1(0x80000000)
|
||||
; CHECK: bb.1
|
||||
successors: %bb.2(0x80000000)
|
||||
|
||||
; CHECK: B %bb.1
|
||||
G_BR %bb.1
|
||||
G_BR %bb.2
|
||||
; CHECK: B %bb.2
|
||||
|
||||
bb.2:
|
||||
; CHECK: bb.2
|
||||
|
||||
BX_RET 14, _
|
||||
; CHECK: BX_RET 14, _
|
||||
...
|
||||
---
|
||||
name: test_soft_fp_double
|
||||
|
@ -431,3 +431,31 @@ entry:
|
||||
infinite:
|
||||
br label %infinite
|
||||
}
|
||||
|
||||
declare arm_aapcscc void @brcond1()
|
||||
declare arm_aapcscc void @brcond2()
|
||||
|
||||
define arm_aapcscc void @test_brcond(i32 %n) {
|
||||
; CHECK-LABEL: test_brcond
|
||||
; CHECK: cmp r0
|
||||
; CHECK-NEXT: movgt [[RCMP:r[0-9]+]], #1
|
||||
; CHECK: tst [[RCMP]], #1
|
||||
; CHECK-NEXT: bne [[FALSE:.L[[:alnum:]_]+]]
|
||||
; CHECK: blx brcond1
|
||||
; CHECK: [[FALSE]]:
|
||||
; CHECK: blx brcond2
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %n, 0
|
||||
br i1 %cmp, label %if.true, label %if.false
|
||||
|
||||
if.true:
|
||||
call arm_aapcscc void @brcond1()
|
||||
br label %if.end
|
||||
|
||||
if.false:
|
||||
call arm_aapcscc void @brcond2()
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
@ -42,6 +42,8 @@
|
||||
define void @test_select_s32() { ret void }
|
||||
define void @test_select_ptr() { ret void }
|
||||
|
||||
define void @test_brcond() { ret void }
|
||||
|
||||
define void @test_fadd_s32() #0 { ret void }
|
||||
define void @test_fadd_s64() #0 { ret void }
|
||||
|
||||
@ -863,6 +865,40 @@ body: |
|
||||
BX_RET 14, _, implicit %r0
|
||||
...
|
||||
---
|
||||
name: test_brcond
|
||||
# CHECK-LABEL: name: test_brcond
|
||||
legalized: false
|
||||
# CHECK: legalized: true
|
||||
regBankSelected: false
|
||||
selected: false
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
body: |
|
||||
bb.0:
|
||||
successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
||||
liveins: %r0, %r1
|
||||
|
||||
%0(s32) = COPY %r0
|
||||
%1(s32) = COPY %r1
|
||||
%2(s1) = G_ICMP intpred(sgt), %0(s32), %1
|
||||
G_BRCOND %2(s1), %bb.1
|
||||
; G_BRCOND with s1 is legal, so we should find it unchanged in the output
|
||||
; CHECK: G_BRCOND {{%[0-9]+}}(s1), %bb.1
|
||||
G_BR %bb.2
|
||||
|
||||
bb.1:
|
||||
%r0 = COPY %1(s32)
|
||||
BX_RET 14, _, implicit %r0
|
||||
|
||||
bb.2:
|
||||
%r0 = COPY %0(s32)
|
||||
BX_RET 14, _, implicit %r0
|
||||
|
||||
...
|
||||
---
|
||||
name: test_fadd_s32
|
||||
# CHECK-LABEL: name: test_fadd_s32
|
||||
legalized: false
|
||||
|
@ -837,16 +837,26 @@ name: test_br
|
||||
legalized: true
|
||||
regBankSelected: false
|
||||
# CHECK: regBankSelected: true
|
||||
# There aren't any registers to map, but make sure we don't crash.
|
||||
selected: false
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
# CHECK: { id: 0, class: gprb, preferred-register: '' }
|
||||
# Check that we map the condition of the G_BRCOND into the GPR.
|
||||
# For the G_BR, there are no registers to map, but make sure we don't crash.
|
||||
body: |
|
||||
bb.0:
|
||||
successors: %bb.1(0x80000000)
|
||||
successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
||||
liveins: %r0
|
||||
|
||||
%0(s1) = COPY %r0
|
||||
G_BRCOND %0(s1), %bb.1
|
||||
G_BR %bb.2
|
||||
|
||||
bb.1:
|
||||
successors: %bb.1(0x80000000)
|
||||
BX_RET 14, _
|
||||
|
||||
G_BR %bb.1
|
||||
bb.2:
|
||||
BX_RET 14, _
|
||||
|
||||
...
|
||||
---
|
||||
|
Loading…
Reference in New Issue
Block a user