Index: lib/Target/Mips/MipsDelaySlotFiller.cpp =================================================================== --- lib/Target/Mips/MipsDelaySlotFiller.cpp +++ lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -188,6 +188,9 @@ private: bool runOnMachineBasicBlock(MachineBasicBlock &MBB); + Iter replaceWithCompactBranch(MachineBasicBlock &MBB, + Iter Branch, DebugLoc DL); + /// This function checks if it is valid to move Candidate to the delay slot /// and returns true if it isn't. It also updates memory and register /// dependence information. @@ -481,6 +484,29 @@ return true; } +// Replace Branch with the compact branch instruction. +Iter Filler::replaceWithCompactBranch(MachineBasicBlock &MBB, + Iter Branch, DebugLoc DL) { + const MipsInstrInfo *TII = + static_cast(TM.getInstrInfo()); + + unsigned NewOpcode = + (((unsigned) Branch->getOpcode()) == Mips::BEQ) ? Mips::BEQZC_MM + : Mips::BNEZC_MM; + + const MCInstrDesc &NewDesc = TII->get(NewOpcode); + MachineInstrBuilder MIB = BuildMI(MBB, Branch, DL, NewDesc); + + MIB.addReg(Branch->getOperand(0).getReg()); + MIB.addMBB(Branch->getOperand(2).getMBB()); + + Iter tmpIter = Branch; + Branch = std::prev(Branch); + MBB.erase(tmpIter); + + return Branch; +} + /// runOnMachineBasicBlock - Fill in delay slots for the given basic block. /// We assume there is only one delay slot per delayed instruction. bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { @@ -506,11 +532,24 @@ } } - // Bundle the NOP to the instruction with the delay slot. - const MipsInstrInfo *TII = - static_cast(TM.getInstrInfo()); - BuildMI(MBB, std::next(I), I->getDebugLoc(), TII->get(Mips::NOP)); - MIBundleBuilder(MBB, I, std::next(I, 2)); + // If instruction is BEQ or BNE with one ZERO register, then instead of + // adding NOP replace this instruction with the corresponding compact + // branch instruction, i.e. BEQZC or BNEZC. + bool IsMicroMips = TM.getSubtarget().inMicroMipsMode(); + unsigned Opcode = I->getOpcode(); + if (IsMicroMips && + (Opcode == Mips::BEQ || Opcode == Mips::BNE) && + ((unsigned) I->getOperand(1).getReg()) == Mips::ZERO) { + + I = replaceWithCompactBranch(MBB, I, I->getDebugLoc()); + + } else { + // Bundle the NOP to the instruction with the delay slot. + const MipsInstrInfo *TII = + static_cast(TM.getInstrInfo()); + BuildMI(MBB, std::next(I), I->getDebugLoc(), TII->get(Mips::NOP)); + MIBundleBuilder(MBB, I, std::next(I, 2)); + } } return Changed; Index: lib/Target/Mips/MipsLongBranch.cpp =================================================================== --- lib/Target/Mips/MipsLongBranch.cpp +++ lib/Target/Mips/MipsLongBranch.cpp @@ -237,11 +237,14 @@ MIB.addMBB(MBBOpnd); - // Bundle the instruction in the delay slot to the newly created branch - // and erase the original branch. - assert(Br->isBundledWithSucc()); - MachineBasicBlock::instr_iterator II(Br); - MIBundleBuilder(&*MIB).append((++II)->removeFromBundle()); + if (((unsigned) Br->getOpcode()) != Mips::BEQZC_MM && + ((unsigned) Br->getOpcode()) != Mips::BNEZC_MM) { + // Bundle the instruction in the delay slot to the newly created branch + // and erase the original branch. + assert(Br->isBundledWithSucc()); + MachineBasicBlock::instr_iterator II(Br); + MIBundleBuilder(&*MIB).append((++II)->removeFromBundle()); + } Br->eraseFromParent(); } Index: lib/Target/Mips/MipsSEInstrInfo.cpp =================================================================== --- lib/Target/Mips/MipsSEInstrInfo.cpp +++ lib/Target/Mips/MipsSEInstrInfo.cpp @@ -353,6 +353,8 @@ case Mips::BLEZ64: return Mips::BGTZ64; case Mips::BC1T: return Mips::BC1F; case Mips::BC1F: return Mips::BC1T; + case Mips::BEQZC_MM: return Mips::BNEZC_MM; + case Mips::BNEZC_MM: return Mips::BEQZC_MM; } } @@ -423,7 +425,7 @@ Opc == Mips::BEQ64 || Opc == Mips::BNE64 || Opc == Mips::BGTZ64 || Opc == Mips::BGEZ64 || Opc == Mips::BLTZ64 || Opc == Mips::BLEZ64 || Opc == Mips::BC1T || Opc == Mips::BC1F || Opc == Mips::B || - Opc == Mips::J) ? + Opc == Mips::J || Opc == Mips::BEQZC_MM || Opc == Mips::BNEZC_MM) ? Opc : 0; } Index: test/CodeGen/Mips/micromips-atomic.ll =================================================================== --- test/CodeGen/Mips/micromips-atomic.ll +++ test/CodeGen/Mips/micromips-atomic.ll @@ -14,5 +14,5 @@ ; CHECK: ll $[[R1:[0-9]+]], 0($[[R0]]) ; CHECK: addu $[[R2:[0-9]+]], $[[R1]], $4 ; CHECK: sc $[[R2]], 0($[[R0]]) -; CHECK: beqz $[[R2]], $[[BB0]] +; CHECK: beqzc $[[R2]], $[[BB0]] } Index: test/CodeGen/Mips/micromips-compact-branches.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/micromips-compact-branches.ll @@ -0,0 +1,19 @@ +; RUN: llc %s -march=mipsel -mattr=micromips -filetype=asm -O3 \ +; RUN: -disable-mips-delay-filler -relocation-model=pic -o - | FileCheck %s + +define void @main() nounwind uwtable { +entry: + %x = alloca i32, align 4 + %0 = load i32* %x, align 4 + %cmp = icmp eq i32 %0, 0 + br i1 %cmp, label %if.then, label %if.end + +if.then: + store i32 10, i32* %x, align 4 + br label %if.end + +if.end: + ret void +} + +; CHECK: bnezc Index: test/CodeGen/Mips/micromips-long-branch.ll =================================================================== --- test/CodeGen/Mips/micromips-long-branch.ll +++ test/CodeGen/Mips/micromips-long-branch.ll @@ -16420,7 +16420,7 @@ ; CHECK: addiu $sp, $sp, -8 ; CHECK: sw $ra, 0($sp) ; CHECK: lui $[[REG1:[0-9]+]], 65534 -; CHECK: addiu $[[REG1]], $[[REG1]], -12 +; CHECK: addiu $[[REG1]], $[[REG1]], -8 ; CHECK: addu $[[REG1]], $ra, $[[REG1]] ; CHECK: lw $ra, 0($sp) ; CHECK: jr $[[REG1]]