Index: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -1835,6 +1835,16 @@ return MadeChange; } +static bool registerDefinedBetween(unsigned Reg, + MachineBasicBlock::iterator From, + MachineBasicBlock::iterator To, + const TargetRegisterInfo *TRI) { + for (auto I = From; I != To; ++I) + if (I->modifiesRegister(Reg, TRI)) + return true; + return false; +} + bool ARMConstantIslands::optimizeThumb2Branches() { bool MadeChange = false; @@ -1899,32 +1909,56 @@ // because the cmp will be eliminated. unsigned BrOffset = getOffsetOf(Br.MI) + 4 - 2; unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset; - if (BrOffset < DestOffset && (DestOffset - BrOffset) <= 126) { - MachineBasicBlock::iterator CmpMI = Br.MI; - if (CmpMI != Br.MI->getParent()->begin()) { - --CmpMI; - if (CmpMI->getOpcode() == ARM::tCMPi8) { - unsigned Reg = CmpMI->getOperand(0).getReg(); - Pred = getInstrPredicate(*CmpMI, PredReg); - if (Pred == ARMCC::AL && - CmpMI->getOperand(1).getImm() == 0 && - isARMLowRegister(Reg)) { - MachineBasicBlock *MBB = Br.MI->getParent(); - LLVM_DEBUG(dbgs() << "Fold: " << *CmpMI << " and: " << *Br.MI); - MachineInstr *NewBR = - BuildMI(*MBB, CmpMI, Br.MI->getDebugLoc(), TII->get(NewOpc)) - .addReg(Reg).addMBB(DestBB,Br.MI->getOperand(0).getTargetFlags()); - CmpMI->eraseFromParent(); - Br.MI->eraseFromParent(); - Br.MI = NewBR; - BBInfo[MBB->getNumber()].Size -= 2; - adjustBBOffsetsAfter(MBB); - ++NumCBZ; - MadeChange = true; - } - } - } + if (BrOffset >= DestOffset || (DestOffset - BrOffset) > 126) + continue; + + // Search backwards to the instruction that defines CSPR + auto *TRI = STI->getRegisterInfo(); + MachineBasicBlock::iterator CmpMI = Br.MI; + while (CmpMI != Br.MI->getParent()->begin()) { + --CmpMI; + if (CmpMI->modifiesRegister(ARM::CPSR, TRI)) + break; } + + // Check that this inst is a CMP r[0-7], #0 and that the register + // is not redefined between the cmp and the br. + if (CmpMI->getOpcode() != ARM::tCMPi8) + continue; + unsigned Reg = CmpMI->getOperand(0).getReg(); + Pred = getInstrPredicate(*CmpMI, PredReg); + if (Pred != ARMCC::AL || CmpMI->getOperand(1).getImm() != 0) + continue; + if (registerDefinedBetween(Reg, CmpMI->getNextNode(), Br.MI, TRI)) + continue; + + // Check for Kill flags on Reg. If they are present remove them and set kill + // on the new CBZ. + MachineBasicBlock::iterator KillMI = Br.MI; + bool RegKilled = false; + do { + --KillMI; + if (KillMI->killsRegister(Reg, TRI)) { + KillMI->clearRegisterKills(Reg, TRI); + RegKilled = true; + break; + } + } while (KillMI != CmpMI); + + // Create the new CBZ/CBNZ + MachineBasicBlock *MBB = Br.MI->getParent(); + LLVM_DEBUG(dbgs() << "Fold: " << *CmpMI << " and: " << *Br.MI); + MachineInstr *NewBR = + BuildMI(*MBB, Br.MI, Br.MI->getDebugLoc(), TII->get(NewOpc)) + .addReg(Reg, getKillRegState(RegKilled)) + .addMBB(DestBB, Br.MI->getOperand(0).getTargetFlags()); + CmpMI->eraseFromParent(); + Br.MI->eraseFromParent(); + Br.MI = NewBR; + BBInfo[MBB->getNumber()].Size -= 2; + adjustBBOffsetsAfter(MBB); + ++NumCBZ; + MadeChange = true; } return MadeChange; @@ -2084,16 +2118,6 @@ DeadSize += 4; } -static bool registerDefinedBetween(unsigned Reg, - MachineBasicBlock::iterator From, - MachineBasicBlock::iterator To, - const TargetRegisterInfo *TRI) { - for (auto I = From; I != To; ++I) - if (I->modifiesRegister(Reg, TRI)) - return true; - return false; -} - /// optimizeThumb2JumpTables - Use tbb / tbh instructions to generate smaller /// jumptables when it's possible. bool ARMConstantIslands::optimizeThumb2JumpTables() { Index: llvm/trunk/test/CodeGen/Thumb2/constant-islands-cbz.ll =================================================================== --- llvm/trunk/test/CodeGen/Thumb2/constant-islands-cbz.ll +++ llvm/trunk/test/CodeGen/Thumb2/constant-islands-cbz.ll @@ -31,10 +31,9 @@ ; CHECK-T2-NEXT: mov r4, r0 ; CHECK-T2-NEXT: movs r0, #0 ; CHECK-T2-NEXT: strd r0, r0, [r4, #4] -; CHECK-T2-NEXT: cmp r2, #0 ; CHECK-T2-NEXT: strd r0, r0, [r4, #12] ; CHECK-T2-NEXT: mov r0, r4 -; CHECK-T2-NEXT: beq .LBB0_2 +; CHECK-T2-NEXT: cbz r2, .LBB0_2 ; CHECK-T2-NEXT: @ %bb.1: @ %if.else ; CHECK-T2-NEXT: bl equeue_create_inplace ; CHECK-T2-NEXT: mov r0, r4 Index: llvm/trunk/test/CodeGen/Thumb2/constant-islands-cbz.mir =================================================================== --- llvm/trunk/test/CodeGen/Thumb2/constant-islands-cbz.mir +++ llvm/trunk/test/CodeGen/Thumb2/constant-islands-cbz.mir @@ -58,9 +58,8 @@ ; CHECK: bb.0: ; CHECK: successors: %bb.2(0x30000000), %bb.1(0x50000000) ; CHECK: renamable $r0, $cpsr = tADDrr killed renamable $r0, renamable $r1, 14, $noreg - ; CHECK: tCMPi8 renamable $r0, 0, 14, $noreg, implicit-def $cpsr ; CHECK: renamable $r1 = t2ADDrs renamable $r0, killed renamable $r1, 18, 14, $noreg, $noreg - ; CHECK: tBcc %bb.2, 0, killed $cpsr + ; CHECK: tCBZ $r0, %bb.2 ; CHECK: bb.1: ; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg :: (load 4 from %ir.x) ; CHECK: tTAILJMPdND @c, 14, $noreg, implicit $sp, implicit $sp, implicit killed $r0 @@ -135,9 +134,8 @@ ; CHECK-LABEL: name: test_notredefined ; CHECK: bb.0: ; CHECK: successors: %bb.2(0x30000000), %bb.1(0x50000000) - ; CHECK: tCMPi8 renamable $r0, 0, 14, $noreg, implicit-def $cpsr ; CHECK: renamable $r1 = t2ADDrs renamable $r0, killed renamable $r1, 18, 14, $noreg, $noreg - ; CHECK: tBcc %bb.2, 0, killed $cpsr + ; CHECK: tCBZ $r0, %bb.2 ; CHECK: bb.1: ; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg :: (load 4 from %ir.x) ; CHECK: tTAILJMPdND @c, 14, $noreg, implicit $sp, implicit $sp, implicit killed $r0 @@ -211,9 +209,8 @@ ; CHECK-LABEL: name: test_killflag_1 ; CHECK: bb.0: ; CHECK: successors: %bb.2(0x30000000), %bb.1(0x50000000) - ; CHECK: tCMPi8 killed renamable $r1, 0, 14, $noreg, implicit-def $cpsr ; CHECK: renamable $r0 = t2ADDrs killed renamable $r0, killed renamable $r0, 18, 14, $noreg, $noreg - ; CHECK: tBcc %bb.2, 0, killed $cpsr + ; CHECK: tCBZ killed $r1, %bb.2 ; CHECK: bb.1: ; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg :: (load 4 from %ir.x) ; CHECK: tTAILJMPdND @c, 14, $noreg, implicit $sp, implicit $sp, implicit killed $r0 @@ -249,9 +246,8 @@ ; CHECK-LABEL: name: test_killflag_2 ; CHECK: bb.0: ; CHECK: successors: %bb.2(0x30000000), %bb.1(0x50000000) - ; CHECK: tCMPi8 renamable $r1, 0, 14, $noreg, implicit-def $cpsr - ; CHECK: renamable $r0 = t2ADDrs killed renamable $r1, killed renamable $r0, 18, 14, $noreg, $noreg - ; CHECK: tBcc %bb.2, 0, killed $cpsr + ; CHECK: renamable $r0 = t2ADDrs renamable $r1, killed renamable $r0, 18, 14, $noreg, $noreg + ; CHECK: tCBZ killed $r1, %bb.2 ; CHECK: bb.1: ; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg :: (load 4 from %ir.x) ; CHECK: tTAILJMPdND @c, 14, $noreg, implicit $sp, implicit $sp, implicit killed $r0