Index: llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp =================================================================== --- llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -1889,6 +1889,16 @@ return false; } +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 ARMBaseInstrInfo:: isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, @@ -1898,23 +1908,32 @@ // If we are optimizing for size, see if the branch in the predecessor can be // lowered to cbn?z by the constant island lowering pass, and return false if - // so. This results in a shorter instruction sequence. + // so. This results in a shorter instruction sequence. This check mirrors that + // in constant island pass. if (MBB.getParent()->getFunction().optForSize()) { MachineBasicBlock *Pred = *MBB.pred_begin(); if (!Pred->empty()) { MachineInstr *LastMI = &*Pred->rbegin(); if (LastMI->getOpcode() == ARM::t2Bcc) { MachineBasicBlock::iterator CmpMI = LastMI; - if (CmpMI != Pred->begin()) { + const TargetRegisterInfo *TRI = &getRegisterInfo(); + while (CmpMI != Pred->begin()) { --CmpMI; - if (CmpMI->getOpcode() == ARM::tCMPi8 || - CmpMI->getOpcode() == ARM::t2CMPri) { - unsigned Reg = CmpMI->getOperand(0).getReg(); - unsigned PredReg = 0; - ARMCC::CondCodes P = getInstrPredicate(*CmpMI, PredReg); - if (P == ARMCC::AL && CmpMI->getOperand(1).getImm() == 0 && - isARMLowRegister(Reg)) - return false; + if (CmpMI->modifiesRegister(ARM::CPSR, TRI)) + break; + if (CmpMI->readsRegister(ARM::CPSR, TRI)) + break; + } + + if (CmpMI->getOpcode() == ARM::tCMPi8 || + CmpMI->getOpcode() == ARM::t2CMPri) { + unsigned Reg = CmpMI->getOperand(0).getReg(); + unsigned PredReg = 0; + ARMCC::CondCodes P = getInstrPredicate(*CmpMI, PredReg); + if (P == ARMCC::AL && CmpMI->getOperand(1).getImm() == 0 && + isARMLowRegister(Reg) && + !registerDefinedBetween(Reg, CmpMI->getNextNode(), LastMI, TRI)) { + return false; } } } Index: llvm/test/CodeGen/Thumb2/ifcvt-cbz.mir =================================================================== --- llvm/test/CodeGen/Thumb2/ifcvt-cbz.mir +++ llvm/test/CodeGen/Thumb2/ifcvt-cbz.mir @@ -133,10 +133,13 @@ body: | ; CHECK-LABEL: name: f3 ; CHECK: bb.0: + ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000) ; CHECK: liveins: $r0, $lr, $r7 ; CHECK: t2CMPri killed renamable $r0, 0, 14, $noreg, implicit-def $cpsr - ; CHECK: dead $r1 = t2MOVi 0, 14, $noreg, $noreg - ; CHECK: tBX_RET 1, killed $cpsr + ; CHECK: $r1 = t2MOVi 0, 14, $noreg, $noreg + ; CHECK: t2Bcc %bb.2, 1, killed $cpsr + ; CHECK: bb.1: + ; CHECK: liveins: $r7, $lr ; CHECK: $sp = frame-setup t2STMDB_UPD $sp, 14, $noreg, killed $r7, killed $lr ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8 ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4 @@ -145,6 +148,9 @@ ; CHECK: tBL 14, $noreg, @fn, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit $r0, implicit-def $sp, implicit-def dead $r0 ; CHECK: $sp = t2LDMIA_UPD $sp, 14, $noreg, def $r7, def $lr ; CHECK: tBX_RET 14, $noreg + ; CHECK: bb.2: + ; CHECK: liveins: $lr, $r7 + ; CHECK: tBX_RET 14, $noreg bb.0: successors: %bb.1(0x40000000), %bb.2(0x40000000) liveins: $r0, $lr, $r7