Index: llvm/include/llvm/CodeGen/ReachingDefAnalysis.h =================================================================== --- llvm/include/llvm/CodeGen/ReachingDefAnalysis.h +++ llvm/include/llvm/CodeGen/ReachingDefAnalysis.h @@ -176,7 +176,7 @@ /// Assuming MI is dead, recursively search the incoming operands which are /// killed by MI and collect those that would become dead. - void collectLocalKilledOperands(MachineInstr *MI, InstSet &Dead) const; + void collectKilledOperands(MachineInstr *MI, InstSet &Dead) const; /// Return whether removing this instruction will have no effect on the /// program, returning the redundant use-def chain. Index: llvm/lib/CodeGen/ReachingDefAnalysis.cpp =================================================================== --- llvm/lib/CodeGen/ReachingDefAnalysis.cpp +++ llvm/lib/CodeGen/ReachingDefAnalysis.cpp @@ -525,8 +525,8 @@ return true; } -void ReachingDefAnalysis::collectLocalKilledOperands(MachineInstr *MI, - InstSet &Dead) const { +void ReachingDefAnalysis::collectKilledOperands(MachineInstr *MI, + InstSet &Dead) const { Dead.insert(MI); auto IsDead = [this](MachineInstr *Def, int PhysReg) { unsigned LiveDefs = 0; @@ -539,15 +539,17 @@ SmallPtrSet Uses; getGlobalUses(Def, PhysReg, Uses); + // This is called when a user is going to be removed, so Def will be dead + // if it only has one user. return Uses.size() == 1; }; for (auto &MO : MI->uses()) { if (!MO.isReg() || MO.getReg() == 0 || !MO.isKill()) continue; - if (MachineInstr *Def = getReachingLocalMIDef(MI, MO.getReg())) + if (MachineInstr *Def = getMIOperand(MI, MO)) if (IsDead(Def, MO.getReg())) - collectLocalKilledOperands(Def, Dead); + collectKilledOperands(Def, Dead); } } Index: llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp =================================================================== --- llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp +++ llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp @@ -901,16 +901,27 @@ if (!Def) return; - // Collect IT blocks. + // Collect the dead code and the MBBs in which they reside. + SmallPtrSet Killed; + RDA->collectKilledOperands(Def, Killed); + SmallPtrSet BasicBlocks; + for (auto *MI : Killed) + BasicBlocks.insert(MI->getParent()); + + // Collect IT blocks in all affected basic blocks. std::map> ITBlocks; std::map Predicates; - MachineInstr *IT = nullptr; - for (auto &MI : *Def->getParent()) { - if (MI.getOpcode() == ARM::t2IT) - IT = &MI; - else if (TII->getPredicate(MI) != ARMCC::AL) { - ITBlocks[IT].insert(&MI); - Predicates[&MI] = IT; + for (auto *MBB : BasicBlocks) { + MachineInstr *IT = nullptr; + for (auto &MI : *MBB) { + if (MI.getOpcode() == ARM::t2IT) + IT = &MI; + else if (IT && TII->getPredicate(MI) != ARMCC::AL) { + ITBlocks[IT].insert(&MI); + Predicates[&MI] = IT; + if (MI.getOperand(MI.getNumOperands()-1).isKill()) + IT = nullptr; + } } } @@ -918,8 +929,6 @@ // also remove the IT instruction. SmallPtrSet ModifiedITs; SmallPtrSet DeadITs; - SmallPtrSet Killed; - RDA->collectLocalKilledOperands(Def, Killed); for (auto *MI : Killed) { if (!Predicates.count(MI)) continue; Index: llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-mov.mir =================================================================== --- llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-mov.mir +++ llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-mov.mir @@ -45,10 +45,7 @@ ; 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 $r1, 4, 14 /* CC::al */, $noreg, implicit-def $cpsr - ; CHECK: renamable $r3 = t2MOVi 4, 14 /* CC::al */, $noreg, $noreg - ; CHECK: t2IT 11, 8, implicit-def $itstate - ; CHECK: dead $r3 = tMOVr renamable $r1, 11 /* CC::lt */, killed $cpsr, implicit killed renamable $r3, implicit killed $itstate + ; CHECK: tCMPi8 renamable $r1, 4, 14 /* CC::al */, $noreg, implicit-def dead $cpsr ; CHECK: tCMPi8 renamable $r1, 2, 14 /* CC::al */, $noreg, implicit-def $cpsr ; CHECK: renamable $r12 = t2MOVi 4, 14 /* CC::al */, $noreg, $noreg ; CHECK: tBcc %bb.2, 2 /* CC::hs */, killed $cpsr