diff options
5 files changed, 59 insertions, 1 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 443b1783729..fcd6e1a3452 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -89,6 +89,8 @@ private: // 3. Create the generic instruction. bool translateADD(const Instruction &Inst); + bool translateBr(const Instruction &Inst); + bool translateReturn(const Instruction &Inst); // Builder for machine instruction a la IRBuilder. diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index e36ca033ca5..36032599b0c 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -98,6 +98,14 @@ public: /// \return The newly created instruction. MachineInstr *buildInstr(unsigned Opcode, Type *Ty); + /// Build and insert <empty> = \p Opcode [\p Ty] \p BB. + /// + /// \pre setBasicBlock or setMI must have been called. + /// \pre Ty == nullptr or isPreISelGenericOpcode(Opcode) + /// + /// \return The newly created instruction. + MachineInstr *buildInstr(unsigned Opcode, Type *Ty, MachineBasicBlock &BB); + /// Build and insert \p Res<def> = \p Opcode [\p Ty] \p Op0, \p Op1. /// /// \pre setBasicBlock or setMI must have been called. diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index fb2f5592b52..6fd179fc50c 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -82,11 +82,30 @@ bool IRTranslator::translateReturn(const Instruction &Inst) { return CLI->LowerReturn(MIRBuilder, Ret, !Ret ? 0 : getOrCreateVReg(*Ret)); } +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.buildInstr(TargetOpcode::G_BR, BrTgt.getType(), TgtBB); + } else { + assert(0 && "Not yet implemented"); + } + // Link successors. + MachineBasicBlock &CurBB = MIRBuilder.getMBB(); + for (const BasicBlock *Succ : BrInst.successors()) + CurBB.addSuccessor(&getOrCreateBB(*Succ)); + return true; +} + bool IRTranslator::translate(const Instruction &Inst) { MIRBuilder.setDebugLoc(Inst.getDebugLoc()); switch(Inst.getOpcode()) { case Instruction::Add: return translateADD(Inst); + case Instruction::Br: + return translateBr(Inst); case Instruction::Ret: return translateReturn(Inst); diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index 2a828d76b07..2f19bcf1e68 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -95,3 +95,10 @@ MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, unsigned Res, MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode) { return buildInstr(Opcode, nullptr); } + +MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, Type *Ty, + MachineBasicBlock &BB) { + MachineInstr *NewMI = buildInstr(Opcode, Ty); + MachineInstrBuilder(getMF(), NewMI).addMBB(&BB); + return NewMI; +} diff --git a/llvm/test/CodeGen/AArch64/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/arm64-irtranslator.ll index ffae84c97da..8baa64df9d8 100644 --- a/llvm/test/CodeGen/AArch64/arm64-irtranslator.ll +++ b/llvm/test/CodeGen/AArch64/arm64-irtranslator.ll @@ -1,4 +1,4 @@ -; RUN: llc -stop-after=irtranslator -global-isel %s -o - 2>&1 | FileCheck %s +; RUN: llc -O0 -stop-after=irtranslator -global-isel %s -o - 2>&1 | FileCheck %s ; REQUIRES: global-isel ; This file checks that the translation from llvm IR to generic MachineInstr ; is correct. @@ -16,3 +16,25 @@ define i64 @addi64(i64 %arg1, i64 %arg2) { %res = add i64 %arg1, %arg2 ret i64 %res } + +; Tests for br. +; CHECK: name: uncondbr +; CHECK: body: +; +; Entry basic block. +; CHECK: {{[0-9a-zA-Z._-]+}}: +; +; Make sure we have one successor and only one. +; CHECK-NEXT: successors: %[[END:[0-9a-zA-Z._-]+]]({{0x[a-f0-9]+ / 0x[a-f0-9]+}} = 100.00%) +; +; Check that we emit the correct branch. +; CHECK: G_BR label %[[END]] +; +; Check that end contains the return instruction. +; CHECK: [[END]]: +; CHECK-NEXT: RET_ReallyLR +define void @uncondbr() { + br label %end +end: + ret void +} |