aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/Mips/Mips16InstrInfo.td1
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp77
-rw-r--r--lib/Target/Mips/MipsISelLowering.h3
-rw-r--r--test/CodeGen/Mips/selTBteqzCmpi.ll26
-rw-r--r--test/CodeGen/Mips/selTBtnezCmpi.ll26
-rw-r--r--test/CodeGen/Mips/selTBtnezSlti.ll25
-rw-r--r--test/CodeGen/Mips/selgek.ll2
-rw-r--r--test/CodeGen/Mips/selltk.ll1
-rw-r--r--test/CodeGen/Mips/selne.ll1
-rw-r--r--test/CodeGen/Mips/selpat.ll8
10 files changed, 166 insertions, 4 deletions
diff --git a/lib/Target/Mips/Mips16InstrInfo.td b/lib/Target/Mips/Mips16InstrInfo.td
index 9e07b95cc6..3c6c7d77a1 100644
--- a/lib/Target/Mips/Mips16InstrInfo.td
+++ b/lib/Target/Mips/Mips16InstrInfo.td
@@ -392,6 +392,7 @@ class SeliT<string op1, string op2>:
!strconcat(op1, "\t.+4\n\tmove $rd, $rs"))), []> {
let isCodeGenOnly=1;
let Constraints = "$rd = $rd_";
+ let usesCustomInserter = 1;
}
//
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index 5605759bd3..f1affff432 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -1298,6 +1298,71 @@ MachineBasicBlock *MipsTargetLowering::EmitSel16(unsigned Opc, MachineInstr *MI,
return BB;
}
+MachineBasicBlock *MipsTargetLowering::EmitSelT16
+ (unsigned Opc1, unsigned Opc2,
+ MachineInstr *MI, MachineBasicBlock *BB) const {
+ if (DontExpandCondPseudos16)
+ return BB;
+ const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
+ DebugLoc dl = MI->getDebugLoc();
+ // To "insert" a SELECT_CC instruction, we actually have to insert the
+ // diamond control-flow pattern. The incoming instruction knows the
+ // destination vreg to set, the condition code register to branch on, the
+ // true/false values to select between, and a branch opcode to use.
+ const BasicBlock *LLVM_BB = BB->getBasicBlock();
+ MachineFunction::iterator It = BB;
+ ++It;
+
+ // thisMBB:
+ // ...
+ // TrueVal = ...
+ // setcc r1, r2, r3
+ // bNE r1, r0, copy1MBB
+ // fallthrough --> copy0MBB
+ MachineBasicBlock *thisMBB = BB;
+ MachineFunction *F = BB->getParent();
+ MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
+ MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
+ F->insert(It, copy0MBB);
+ F->insert(It, sinkMBB);
+
+ // Transfer the remainder of BB and its successor edges to sinkMBB.
+ sinkMBB->splice(sinkMBB->begin(), BB,
+ llvm::next(MachineBasicBlock::iterator(MI)),
+ BB->end());
+ sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
+
+ // Next, add the true and fallthrough blocks as its successors.
+ BB->addSuccessor(copy0MBB);
+ BB->addSuccessor(sinkMBB);
+
+ BuildMI(BB, dl, TII->get(Opc2)).addReg(MI->getOperand(3).getReg())
+ .addImm(MI->getOperand(4).getImm());
+ BuildMI(BB, dl, TII->get(Opc1)).addMBB(sinkMBB);
+
+ // copy0MBB:
+ // %FalseValue = ...
+ // # fallthrough to sinkMBB
+ BB = copy0MBB;
+
+ // Update machine-CFG edges
+ BB->addSuccessor(sinkMBB);
+
+ // sinkMBB:
+ // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
+ // ...
+ BB = sinkMBB;
+
+ BuildMI(*BB, BB->begin(), dl,
+ TII->get(Mips::PHI), MI->getOperand(0).getReg())
+ .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB)
+ .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB);
+
+ MI->eraseFromParent(); // The pseudo instruction is gone now.
+ return BB;
+
+}
+
MachineBasicBlock *
MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *BB) const {
@@ -1413,6 +1478,18 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
return EmitSel16(Mips::BeqzRxImm16, MI, BB);
case Mips::SelBneZ:
return EmitSel16(Mips::BnezRxImm16, MI, BB);
+ case Mips::SelTBteqZCmpi:
+ return EmitSelT16(Mips::BteqzX16, Mips::CmpiRxImmX16, MI, BB);
+ case Mips::SelTBteqZSlti:
+ return EmitSelT16(Mips::BteqzX16, Mips::SltiRxImmX16, MI, BB);
+ case Mips::SelTBteqZSltiu:
+ return EmitSelT16(Mips::BteqzX16, Mips::SltiuRxImmX16, MI, BB);
+ case Mips::SelTBtneZCmpi:
+ return EmitSelT16(Mips::BtnezX16, Mips::CmpiRxImmX16, MI, BB);
+ case Mips::SelTBtneZSlti:
+ return EmitSelT16(Mips::BtnezX16, Mips::SltiRxImmX16, MI, BB);
+ case Mips::SelTBtneZSltiu:
+ return EmitSelT16(Mips::BtnezX16, Mips::SltiuRxImmX16, MI, BB);
}
}
diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h
index 2531a20b0f..834391536a 100644
--- a/lib/Target/Mips/MipsISelLowering.h
+++ b/lib/Target/Mips/MipsISelLowering.h
@@ -406,6 +406,9 @@ namespace llvm {
MachineBasicBlock *BB, unsigned Size) const;
MachineBasicBlock *EmitSel16(unsigned Opc, MachineInstr *MI,
MachineBasicBlock *BB) const;
+ MachineBasicBlock *EmitSelT16(unsigned Opc1, unsigned Opc2,
+ MachineInstr *MI,
+ MachineBasicBlock *BB) const;
};
}
diff --git a/test/CodeGen/Mips/selTBteqzCmpi.ll b/test/CodeGen/Mips/selTBteqzCmpi.ll
new file mode 100644
index 0000000000..9cb8227f9d
--- /dev/null
+++ b/test/CodeGen/Mips/selTBteqzCmpi.ll
@@ -0,0 +1,26 @@
+; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic < %s | FileCheck %s -check-prefix=16
+
+@i = global i32 1, align 4
+@j = global i32 2, align 4
+@a = global i32 5, align 4
+@.str = private unnamed_addr constant [8 x i8] c"%i = 2\0A\00", align 1
+@k = common global i32 0, align 4
+
+define void @t() nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" {
+entry:
+ %0 = load i32* @a, align 4
+ %cmp = icmp eq i32 %0, 10
+ %1 = load i32* @i, align 4
+ %2 = load i32* @j, align 4
+ %cond = select i1 %cmp, i32 %1, i32 %2
+ store i32 %cond, i32* @i, align 4
+ ret void
+}
+
+attributes #0 = { nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" }
+
+
+; 16: cmpi ${{[0-9]+}}, 10
+; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}}
+
+
diff --git a/test/CodeGen/Mips/selTBtnezCmpi.ll b/test/CodeGen/Mips/selTBtnezCmpi.ll
new file mode 100644
index 0000000000..bd334f59d3
--- /dev/null
+++ b/test/CodeGen/Mips/selTBtnezCmpi.ll
@@ -0,0 +1,26 @@
+; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic < %s | FileCheck %s -check-prefix=16
+
+@i = global i32 1, align 4
+@j = global i32 2, align 4
+@a = global i32 5, align 4
+@.str = private unnamed_addr constant [8 x i8] c"%i = 1\0A\00", align 1
+@k = common global i32 0, align 4
+
+define void @t() nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" {
+entry:
+ %0 = load i32* @a, align 4
+ %cmp = icmp ne i32 %0, 10
+ %1 = load i32* @i, align 4
+ %2 = load i32* @j, align 4
+ %cond = select i1 %cmp, i32 %1, i32 %2
+ store i32 %cond, i32* @i, align 4
+ ret void
+}
+
+; 16: cmpi ${{[0-9]+}}, 10
+; 16: btnez $BB{{[0-9]+}}_{{[0-9]}}
+
+
+attributes #0 = { nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" }
+
+
diff --git a/test/CodeGen/Mips/selTBtnezSlti.ll b/test/CodeGen/Mips/selTBtnezSlti.ll
new file mode 100644
index 0000000000..593f6f274e
--- /dev/null
+++ b/test/CodeGen/Mips/selTBtnezSlti.ll
@@ -0,0 +1,25 @@
+; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic < %s | FileCheck %s -check-prefix=16
+
+@i = global i32 1, align 4
+@j = global i32 2, align 4
+@a = global i32 5, align 4
+@.str = private unnamed_addr constant [9 x i8] c"%i = 2 \0A\00", align 1
+@k = common global i32 0, align 4
+
+define void @t() nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" {
+entry:
+ %0 = load i32* @a, align 4
+ %cmp = icmp slt i32 %0, 10
+ %1 = load i32* @j, align 4
+ %2 = load i32* @i, align 4
+ %cond = select i1 %cmp, i32 %1, i32 %2
+ store i32 %cond, i32* @i, align 4
+ ret void
+}
+
+attributes #0 = { nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" }
+
+; 16: slti ${{[0-9]+}}, 10
+; 16: btnez $BB{{[0-9]+}}_{{[0-9]}}
+
+
diff --git a/test/CodeGen/Mips/selgek.ll b/test/CodeGen/Mips/selgek.ll
index 0574d0d699..8ab4046e92 100644
--- a/test/CodeGen/Mips/selgek.ll
+++ b/test/CodeGen/Mips/selgek.ll
@@ -90,3 +90,5 @@ attributes #1 = { "target-cpu"="mips16" "target-features"="+mips16,+o32" }
; 16: slti ${{[0-9]+}}, 2 # 16 bit inst
; 16: btnez $BB{{[0-9]+}}_{{[0-9]}}
+
+
diff --git a/test/CodeGen/Mips/selltk.ll b/test/CodeGen/Mips/selltk.ll
index e0b2af2912..1471b892c9 100644
--- a/test/CodeGen/Mips/selltk.ll
+++ b/test/CodeGen/Mips/selltk.ll
@@ -90,3 +90,4 @@ attributes #1 = { "target-cpu"="mips16" "target-features"="+mips16,+o32" }
; 16: slti ${{[0-9]+}}, 3 # 16 bit inst
; 16: btnez $BB{{[0-9]+}}_{{[0-9]}}
+
diff --git a/test/CodeGen/Mips/selne.ll b/test/CodeGen/Mips/selne.ll
index 2987a9f61f..e3d82b8cf5 100644
--- a/test/CodeGen/Mips/selne.ll
+++ b/test/CodeGen/Mips/selne.ll
@@ -94,3 +94,4 @@ attributes #1 = { "target-cpu"="mips16" "target-features"="+mips16,+o32" }
; 16: cmp ${{[0-9]+}}, ${{[0-9]+}}
; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}}
+
diff --git a/test/CodeGen/Mips/selpat.ll b/test/CodeGen/Mips/selpat.ll
index 57cc126bed..721cb9fa27 100644
--- a/test/CodeGen/Mips/selpat.ll
+++ b/test/CodeGen/Mips/selpat.ll
@@ -41,7 +41,7 @@ entry:
%cond = select i1 %cmp, i32 %1, i32 %2
store i32 %cond, i32* @z1, align 4
; 16: cmpi ${{[0-9]+}}, 1
-; 16: bteqz .+4
+; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}}
; 16: move ${{[0-9]+}}, ${{[0-9]+}}
%cmp1 = icmp eq i32 %0, 10
%cond5 = select i1 %cmp1, i32 %2, i32 %1
@@ -51,7 +51,7 @@ entry:
%cond10 = select i1 %cmp6, i32 %2, i32 %1
store i32 %cond10, i32* @z3, align 4
; 16: cmpi ${{[0-9]+}}, 10
-; 16: bteqz .+4
+; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}}
; 16: move ${{[0-9]+}}, ${{[0-9]+}}
%cmp11 = icmp eq i32 %3, 10
%cond15 = select i1 %cmp11, i32 %1, i32 %2
@@ -212,7 +212,7 @@ entry:
%cond = select i1 %cmp, i32 %1, i32 %2
store i32 %cond, i32* @z1, align 4
; 16: cmpi ${{[0-9]+}}, 1
-; 16: btnez .+4
+; 16: btnez $BB{{[0-9]+}}_{{[0-9]}}
; 16: move ${{[0-9]+}}, ${{[0-9]+}}
%cmp1 = icmp ne i32 %0, 10
%cond5 = select i1 %cmp1, i32 %2, i32 %1
@@ -222,7 +222,7 @@ entry:
%cond10 = select i1 %cmp6, i32 %2, i32 %1
store i32 %cond10, i32* @z3, align 4
; 16: cmpi ${{[0-9]+}}, 10
-; 16: btnez .+4
+; 16: btnez $BB{{[0-9]+}}_{{[0-9]}}
; 16: move ${{[0-9]+}}, ${{[0-9]+}}
%cmp11 = icmp ne i32 %3, 10
%cond15 = select i1 %cmp11, i32 %1, i32 %2