diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp --- a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp +++ b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp @@ -21,6 +21,30 @@ INITIALIZE_PASS(ReachingDefAnalysis, DEBUG_TYPE, "ReachingDefAnalysis", false, true) +bool isValidReg(const MachineOperand &MO) { + return MO.isReg() && MO.getReg(); +} + +bool isValidRegUse(const MachineOperand &MO) { + return isValidReg(MO) && MO.isUse(); +} + +bool isValidRegUseOf(const MachineOperand &MO, int PhysReg) { + return isValidRegUse(MO) && MO.getReg() == PhysReg; +} + +bool isKilledRegUse(const MachineOperand &MO) { + return isValidRegUse(MO) && MO.isKill(); +} + +bool isValidRegDef(const MachineOperand &MO) { + return isValidReg(MO) && MO.isDef(); +} + +bool isValidRegDefOf(const MachineOperand &MO, int PhysReg) { + return isValidRegDef(MO) && MO.getReg() == PhysReg; +} + void ReachingDefAnalysis::enterBasicBlock( const LoopTraversal::TraversedMBBInfo &TraversedMBB) { @@ -100,14 +124,9 @@ unsigned MBBNumber = MI->getParent()->getNumber(); assert(MBBNumber < MBBReachingDefs.size() && "Unexpected basic block number."); - const MCInstrDesc &MCID = MI->getDesc(); - for (unsigned i = 0, - e = MI->isVariadic() ? MI->getNumOperands() : MCID.getNumDefs(); - i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg() || !MO.getReg()) - continue; - if (MO.isUse()) + + for (auto &MO : MI->operands()) { + if (!isValidRegDef(MO)) continue; for (MCRegUnitIterator Unit(MO.getReg(), TRI); Unit.isValid(); ++Unit) { // This instruction explicitly defines the current reg unit. @@ -254,7 +273,7 @@ return; for (auto &MO : MI->operands()) { - if (!MO.isReg() || !MO.isUse() || MO.getReg() != PhysReg) + if (!isValidRegUseOf(MO, PhysReg)) continue; Uses.insert(&*MI); @@ -271,7 +290,7 @@ if (MI.isDebugInstr()) continue; for (auto &MO : MI.operands()) { - if (!MO.isReg() || !MO.isUse() || MO.getReg() != PhysReg) + if (!isValidRegUseOf(MO, PhysReg)) continue; if (getReachingDef(&MI, PhysReg) >= 0) return false; @@ -410,7 +429,7 @@ // Finally check that the last instruction doesn't redefine the register. for (auto &MO : Last->operands()) - if (MO.isReg() && MO.isDef() && MO.getReg() == PhysReg) + if (isValidRegDefOf(MO, PhysReg)) return false; return true; @@ -426,7 +445,7 @@ MachineInstr *Last = &MBB->back(); int Def = getReachingDef(Last, PhysReg); for (auto &MO : Last->operands()) - if (MO.isReg() && MO.isDef() && MO.getReg() == PhysReg) + if (isValidRegDefOf(MO, PhysReg)) return Last; return Def < 0 ? nullptr : getInstFromId(MBB, Def); @@ -450,7 +469,7 @@ SmallSet Defs; // First check that From would compute the same value if moved. for (auto &MO : From->operands()) { - if (!MO.isReg() || MO.isUndef() || !MO.getReg()) + if (!isValidReg(MO)) continue; if (MO.isDef()) Defs.insert(MO.getReg()); @@ -508,7 +527,7 @@ Visited.insert(MI); for (auto &MO : MI->operands()) { - if (!MO.isReg() || MO.isUse() || MO.getReg() == 0) + if (!isValidRegDef(MO)) continue; SmallPtrSet Uses; @@ -530,9 +549,12 @@ Dead.insert(MI); auto IsDead = [this](MachineInstr *Def, int PhysReg) { unsigned LiveDefs = 0; - for (auto &MO : Def->defs()) + for (auto &MO : Def->operands()) { + if (!isValidRegDef(MO)) + continue; if (!MO.isDead()) ++LiveDefs; + } if (LiveDefs > 1) return false; @@ -542,8 +564,8 @@ return Uses.size() == 1; }; - for (auto &MO : MI->uses()) { - if (!MO.isReg() || MO.getReg() == 0 || !MO.isKill()) + for (auto &MO : MI->operands()) { + if (!isKilledRegUse(MO)) continue; if (MachineInstr *Def = getReachingLocalMIDef(MI, MO.getReg())) if (IsDead(Def, MO.getReg())) @@ -579,7 +601,7 @@ if (Ignore.count(&*I)) continue; for (auto &MO : I->operands()) - if (MO.isReg() && MO.isDef() && MO.getReg() == PhysReg) + if (isValidRegDefOf(MO, PhysReg)) return false; } } diff --git a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp --- a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp +++ b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp @@ -815,10 +815,13 @@ bool ARMLowOverheadLoops::RevertLoopDec(MachineInstr *MI) const { LLVM_DEBUG(dbgs() << "ARM Loops: Reverting to sub: " << *MI); MachineBasicBlock *MBB = MI->getParent(); - MachineInstr *Last = &MBB->back(); SmallPtrSet Ignore; - if (Last->getOpcode() == ARM::t2LoopEnd) - Ignore.insert(Last); + for (auto I = MachineBasicBlock::iterator(MI), E = MBB->end(); I != E; ++I) { + if (I->getOpcode() == ARM::t2LoopEnd) { + Ignore.insert(&*I); + break; + } + } // If nothing defines CPSR between LoopDec and LoopEnd, use a t2SUBS. bool SetFlags = RDA->isSafeToDefRegAt(MI, ARM::CPSR, Ignore); diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/cmplx_cong.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/cmplx_cong.mir --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/cmplx_cong.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/cmplx_cong.mir @@ -38,13 +38,12 @@ ; CHECK-LABEL: name: arm_cmplx_conj_f32_mve ; CHECK: bb.0: ; CHECK: successors: %bb.1(0x80000000) - ; CHECK: liveins: $lr, $r0, $r1, $r3, $r4 + ; CHECK: liveins: $lr, $r0, $r1, $r2, $r4 ; CHECK: frame-setup tPUSH 14 /* CC::al */, $noreg, killed $r4, killed $lr, implicit-def $sp, implicit $sp ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8 ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4 ; CHECK: frame-setup CFI_INSTRUCTION offset $r4, -8 - ; CHECK: tCMPi8 renamable $r3, 4, 14 /* CC::al */, $noreg, implicit-def dead $cpsr - ; FIXME: tLSRi needs to be producing the value in r3 + ; CHECK: renamable $r3, dead $cpsr = tLSLri killed renamable $r2, 1, 14 /* CC::al */, $noreg ; CHECK: $r4 = t2MOVi16 target-flags(arm-lo16) @arm_cmplx_conj_f32_mve.cmplx_conj_sign, 14 /* CC::al */, $noreg ; CHECK: $r4 = t2MOVTi16 killed $r4, target-flags(arm-hi16) @arm_cmplx_conj_f32_mve.cmplx_conj_sign, 14 /* CC::al */, $noreg ; CHECK: renamable $q0 = nnan ninf nsz MVE_VLDRWU32 killed renamable $r4, 0, 0, $noreg diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/dont-ignore-vctp.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/dont-ignore-vctp.mir --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/dont-ignore-vctp.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/dont-ignore-vctp.mir @@ -95,12 +95,12 @@ ; CHECK-LABEL: name: dont_ignore_vctp ; CHECK: bb.0.entry: ; CHECK: successors: %bb.1(0x80000000) - ; CHECK: liveins: $lr, $r0, $r1, $r3, $r7 + ; CHECK: liveins: $lr, $r0, $r1, $r2, $r7 ; CHECK: frame-setup tPUSH 14 /* CC::al */, $noreg, killed $r7, killed $lr, implicit-def $sp, implicit $sp ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8 ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4 ; CHECK: frame-setup CFI_INSTRUCTION offset $r7, -8 - ; CHECK: tCMPi8 renamable $r3, 4, 14 /* CC::al */, $noreg, implicit-def dead $cpsr + ; CHECK: renamable $r3, dead $cpsr = tLSLri killed renamable $r2, 1, 14 /* CC::al */, $noreg ; CHECK: renamable $r2 = tLEApcrel %const.0, 14 /* CC::al */, $noreg ; CHECK: renamable $q0 = MVE_VLDRWU32 killed renamable $r2, 0, 0, $noreg :: (load 16 from constant-pool) ; CHECK: $lr = MVE_DLSTP_32 killed renamable $r3