diff options
-rw-r--r-- | lib/Target/Mips/Mips16InstrInfo.td | 1 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 77 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.h | 3 | ||||
-rw-r--r-- | test/CodeGen/Mips/selTBteqzCmpi.ll | 26 | ||||
-rw-r--r-- | test/CodeGen/Mips/selTBtnezCmpi.ll | 26 | ||||
-rw-r--r-- | test/CodeGen/Mips/selTBtnezSlti.ll | 25 | ||||
-rw-r--r-- | test/CodeGen/Mips/selgek.ll | 2 | ||||
-rw-r--r-- | test/CodeGen/Mips/selltk.ll | 1 | ||||
-rw-r--r-- | test/CodeGen/Mips/selne.ll | 1 | ||||
-rw-r--r-- | test/CodeGen/Mips/selpat.ll | 8 |
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 |