summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h2
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h8
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp19
-rw-r--r--llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp7
-rw-r--r--llvm/test/CodeGen/AArch64/arm64-irtranslator.ll24
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
+}
OpenPOWER on IntegriCloud