1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

GlobalISel: add generic conditional branch.

Just the basic equivalent to DAG's condbr for now, we'll get to things like
br_cc when we start doing more legalization.

llvm-svn: 277184
This commit is contained in:
Tim Northover 2016-07-29 17:58:00 +00:00
parent 3adce2360c
commit ca6435867c
6 changed files with 75 additions and 7 deletions

View File

@ -140,6 +140,17 @@ public:
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildBr(MachineBasicBlock &BB);
/// Build and insert G_BRCOND \p Ty \p Tst, \p Dest
///
/// G_BRCOND is a conditional branch to \p Dest. At the beginning of
/// legalization, \p Ty will be a single bit (s1). Targets with interesting
/// flags registers may change this.
///
/// \pre setBasicBlock or setMI must have been called.
///
/// \return The newly created instruction.
MachineInstrBuilder buildBrCond(LLT Ty, unsigned Tst, MachineBasicBlock &BB);
/// Build and insert \p Res<def> = COPY Op
///
/// Register-to-register COPY sets \p Res to \p Op.

View File

@ -135,6 +135,16 @@ def G_BR : Instruction {
let hasSideEffects = 0;
let isBranch = 1;
let isTerminator = 1;
let isBarrier = 1;
}
// Generic conditional branch.
def G_BRCOND : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins unknown:$tst, unknown:$truebb);
let hasSideEffects = 0;
let isBranch = 1;
let isTerminator = 1;
}
// TODO: Add the other generic opcodes.

View File

@ -199,6 +199,9 @@ HANDLE_TARGET_OPCODE(G_LOAD)
/// Generic store.
HANDLE_TARGET_OPCODE(G_STORE)
/// Generic conditional branch instruction.
HANDLE_TARGET_OPCODE(G_BRCOND)
/// Generic BRANCH instruction. This is an unconditional branch.
HANDLE_TARGET_OPCODE(G_BR)

View File

@ -104,13 +104,20 @@ bool IRTranslator::translateReturn(const Instruction &Inst) {
bool IRTranslator::translateBr(const Instruction &Inst) {
assert(isa<BranchInst>(Inst) && "Branch expected");
const BranchInst &BrInst = *cast<BranchInst>(&Inst);
if (BrInst.isUnconditional()) {
const BasicBlock &BrTgt = *cast<BasicBlock>(BrInst.getOperand(0));
MachineBasicBlock &TgtBB = getOrCreateBB(BrTgt);
MIRBuilder.buildBr(TgtBB);
} else {
assert(0 && "Not yet implemented");
unsigned Succ = 0;
if (!BrInst.isUnconditional()) {
// We want a G_BRCOND to the true BB followed by an unconditional branch.
unsigned Tst = getOrCreateVReg(*BrInst.getCondition());
const BasicBlock &TrueTgt = *cast<BasicBlock>(BrInst.getSuccessor(Succ++));
MachineBasicBlock &TrueBB = getOrCreateBB(TrueTgt);
MIRBuilder.buildBrCond(LLT{*BrInst.getCondition()->getType()}, Tst, TrueBB);
}
const BasicBlock &BrTgt = *cast<BasicBlock>(BrInst.getSuccessor(Succ));
MachineBasicBlock &TgtBB = getOrCreateBB(BrTgt);
MIRBuilder.buildBr(TgtBB);
// Link successors.
MachineBasicBlock &CurBB = MIRBuilder.getMBB();
for (const BasicBlock *Succ : BrInst.successors())

View File

@ -95,7 +95,13 @@ MachineInstrBuilder MachineIRBuilder::buildCopy(unsigned Res, unsigned Op) {
return buildInstr(TargetOpcode::COPY).addDef(Res).addUse(Op);
}
MachineInstrBuilder MachineIRBuilder::buildLoad(LLT VTy, LLT PTy, unsigned Res,
MachineInstrBuilder MachineIRBuilder::buildBrCond(LLT Ty, unsigned Tst,
MachineBasicBlock &Dest) {
return buildInstr(TargetOpcode::G_BRCOND, Ty).addUse(Tst).addMBB(&Dest);
}
MachineInstrBuilder MachineIRBuilder::buildLoad(LLT VTy, LLT PTy, unsigned Res,
unsigned Addr,
MachineMemOperand &MMO) {
return buildInstr(TargetOpcode::G_LOAD, {VTy, PTy})

View File

@ -58,6 +58,37 @@ end:
ret void
}
; Tests for conditional br.
; CHECK-LABEL: name: condbr
; CHECK: body:
;
; Entry basic block.
; CHECK: {{[0-9a-zA-Z._-]+}}:
;
; Make sure we have two successors
; CHECK-NEXT: successors: %[[TRUE:[0-9a-zA-Z._-]+]]({{0x[a-f0-9]+ / 0x[a-f0-9]+}} = 50.00%),
; CHECK: %[[FALSE:[0-9a-zA-Z._-]+]]({{0x[a-f0-9]+ / 0x[a-f0-9]+}} = 50.00%)
;
; Check that we emit the correct branch.
; CHECK: [[ADDR:%.*]](64) = COPY %x0
; CHECK: [[TST:%.*]](1) = G_LOAD { s1, p0 } [[ADDR]]
; CHECK: G_BRCOND s1 [[TST]], %[[TRUE]]
; CHECK: G_BR unsized %[[FALSE]]
;
; Check that each successor contains the return instruction.
; CHECK: [[TRUE]]:
; CHECK-NEXT: RET_ReallyLR
; CHECK: [[FALSE]]:
; CHECK-NEXT: RET_ReallyLR
define void @condbr(i1* %tstaddr) {
%tst = load i1, i1* %tstaddr
br i1 %tst, label %true, label %false
true:
ret void
false:
ret void
}
; Tests for or.
; CHECK-LABEL: name: ori64
; CHECK: [[ARG1:%[0-9]+]](64) = COPY %x0