Skip to content

Commit dce609b

Browse files
committed
Try to fix clobbering lanes in other assigned lanes of physreg
1 parent 7a2b0b5 commit dce609b

File tree

1 file changed

+72
-1
lines changed

1 file changed

+72
-1
lines changed

llvm/lib/CodeGen/VirtRegMap.cpp

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,9 @@ class VirtRegRewriter : public MachineFunctionPass {
202202
bool needLiveOutUndefSubregDef(const LiveInterval &LI,
203203
const MachineBasicBlock &MBB, unsigned SubReg,
204204
MCPhysReg PhysReg) const;
205+
LaneBitmask liveOutUndefPhiLanesForUndefSubregDef(
206+
const LiveInterval &LI, const MachineBasicBlock &MBB, unsigned SubReg,
207+
MCPhysReg PhysReg, const MachineInstr &MI) const;
205208

206209
public:
207210
static char ID;
@@ -555,6 +558,41 @@ bool VirtRegRewriter::needLiveOutUndefSubregDef(const LiveInterval &LI,
555558
return false;
556559
}
557560

561+
/// Compute a lanemask for undef lanes which need to be preserved out of the
562+
/// defining block for a register assignment.
563+
LaneBitmask VirtRegRewriter::liveOutUndefPhiLanesForUndefSubregDef(
564+
const LiveInterval &LI, const MachineBasicBlock &MBB, unsigned SubReg,
565+
MCPhysReg PhysReg, const MachineInstr &MI) const {
566+
LaneBitmask UndefMask = ~TRI->getSubRegIndexLaneMask(SubReg);
567+
LaneBitmask LiveOutUndefLanes;
568+
569+
for (const LiveInterval::SubRange &SR : LI.subranges()) {
570+
LaneBitmask NeedImpDefLanes = UndefMask & SR.LaneMask;
571+
if (NeedImpDefLanes.any() && !LIS->isLiveOutOfMBB(SR, &MBB)) {
572+
for (const MachineBasicBlock *Succ : MBB.successors()) {
573+
if (LIS->isLiveInToMBB(SR, Succ))
574+
LiveOutUndefLanes |= NeedImpDefLanes;
575+
}
576+
}
577+
}
578+
if (LiveOutUndefLanes.none())
579+
return LiveOutUndefLanes;
580+
581+
SlotIndex MIIndex = LIS->getInstructionIndex(MI);
582+
SlotIndex BeforeMIUses = MIIndex.getBaseIndex();
583+
SlotIndex AfterMIDefs = MIIndex.getBoundaryIndex();
584+
585+
for (MCRegUnitMaskIterator MCRU(PhysReg, TRI); MCRU.isValid(); ++MCRU) {
586+
auto [RU, PhysRegMask] = *MCRU;
587+
588+
const LiveRange &UnitRange = LIS->getRegUnit(RU);
589+
if (UnitRange.liveAt(AfterMIDefs) && UnitRange.liveAt(BeforeMIUses))
590+
LiveOutUndefLanes &= ~PhysRegMask;
591+
}
592+
593+
return LiveOutUndefLanes;
594+
}
595+
558596
void VirtRegRewriter::rewrite() {
559597
bool NoSubRegLiveness = !MRI->subRegLivenessEnabled();
560598
SmallVector<Register, 8> SuperDeads;
@@ -611,8 +649,41 @@ void VirtRegRewriter::rewrite() {
611649
assert(MO.isDef());
612650
if (MO.isUndef()) {
613651
const LiveInterval &LI = LIS->getInterval(VirtReg);
614-
if (needLiveOutUndefSubregDef(LI, *MBBI, SubReg, PhysReg))
652+
653+
LaneBitmask LiveOutUndefLanes =
654+
liveOutUndefPhiLanesForUndefSubregDef(LI, *MBBI, SubReg,
655+
PhysReg, MI);
656+
if (LiveOutUndefLanes.any()) {
657+
SmallVector<unsigned, 16> CoveringIndexes;
658+
659+
// TODO: Just use the super register if
660+
if (TRI->getCoveringSubRegIndexes(
661+
*MRI, MRI->getRegClass(VirtReg), LiveOutUndefLanes,
662+
CoveringIndexes)) {
663+
// Try to represent the minimum needed live out def as a
664+
// sequence of subregister defs.
665+
//
666+
// FIXME: It would be better if we could directly represent
667+
// liveness with a lanemask instead of spamming operands.
668+
for (unsigned SubIdx : CoveringIndexes)
669+
SuperDefs.push_back(TRI->getSubReg(PhysReg, SubIdx));
670+
} else {
671+
// If we could not represent this as a sequence of
672+
// subregisters, it's safe to replace all the lanes with a
673+
// full def of the super register.
674+
SuperDefs.push_back(PhysReg);
675+
}
676+
}
677+
678+
if (false &&
679+
needLiveOutUndefSubregDef(LI, *MBBI, SubReg, PhysReg)) {
615680
SuperDefs.push_back(PhysReg);
681+
682+
for (MCRegister AssignedSubReg : TRI->subregs(PhysReg)) {
683+
if (subRegLiveThrough(MI, AssignedSubReg))
684+
SuperKills.push_back(AssignedSubReg);
685+
}
686+
}
616687
}
617688
}
618689
}

0 commit comments

Comments
 (0)