Index: include/llvm/Target/TargetRegisterInfo.h =================================================================== --- include/llvm/Target/TargetRegisterInfo.h +++ include/llvm/Target/TargetRegisterInfo.h @@ -373,6 +373,19 @@ return SubRegIndexLaneMasks[SubIdx]; } + /// Returns true if the given lane mask is imprecise. + /// + /// LaneMasks as given by getSubRegIndexLaneMask() have a limited number of + /// bits, so there may be cases where: + /// getSubReg(Reg,A) does not overlap getSubReg(Reg,B) + /// but we still have + /// (getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B)) != 0. + /// (Currently this only happens when the target has more than 31 disjunct + /// subregister indices) + static bool isImpreciseLaneMask(unsigned LaneMask) { + return LaneMask & 0x80000000u; + } + /// The lane masks returned by getSubRegIndexLaneMask() above can only be /// used to determine if sub-registers overlap - they can't be used to /// determine if a set of sub-registers completely cover another Index: lib/CodeGen/RegisterCoalescer.cpp =================================================================== --- lib/CodeGen/RegisterCoalescer.cpp +++ lib/CodeGen/RegisterCoalescer.cpp @@ -2633,7 +2633,8 @@ // "overflow bit" 32. As a workaround we drop all subregister ranges // which means we loose some precision but are back to a well defined // state. - assert((CP.getNewRC()->getLaneMask() & 0x80000000u) + assert(TargetRegisterInfo::isImpreciseLaneMask( + CP.getNewRC()->getLaneMask()) && "SubRange merge should only fail when merging into bit 32."); DEBUG(dbgs() << "\tSubrange join aborted!\n"); LHS.clearSubRanges(); Index: lib/CodeGen/VirtRegMap.cpp =================================================================== --- lib/CodeGen/VirtRegMap.cpp +++ lib/CodeGen/VirtRegMap.cpp @@ -167,6 +167,7 @@ void rewrite(); void addMBBLiveIns(); + bool readsUndefSubreg(const MachineOperand &MO) const; public: static char ID; VirtRegRewriter() : MachineFunctionPass(ID) {} @@ -288,6 +289,34 @@ MBB.sortUniqueLiveIns(); } +/// Return true if the given machine operand \p MO - which must be a subregister +/// use - only reads undefined lanes. +bool VirtRegRewriter::readsUndefSubreg(const MachineOperand &MO) const { + // Shortcut if the operand is already marked undef. + if (MO.isUndef()) + return true; + + unsigned Reg = MO.getReg(); + unsigned SubRegIdx = MO.getSubReg(); + assert(SubRegIdx != 0); + const MachineInstr &MI = *MO.getParent(); + SlotIndex BaseIndex = LIS->getInstructionIndex(&MI); + const LiveInterval &LI = LIS->getInterval(Reg); + // This code is only meant to handle reading undefined subregisters which + // we couldn't properly detect before. + assert(LI.liveAt(BaseIndex) && + "Reads of completely dead register should be marked undef already"); + unsigned UseMask = TRI->getSubRegIndexLaneMask(SubRegIdx); + // See if any of the relevant subregister liveranges is defined at this point. + for (const LiveInterval::SubRange &SR : LI.subranges()) { + if ((SR.LaneMask & UseMask) == 0) + continue; + if (SR.liveAt(BaseIndex)) + return false; + } + return true; +} + void VirtRegRewriter::rewrite() { bool NoSubRegLiveness = !MRI->subRegLivenessEnabled(); SmallVector SuperDeads; @@ -367,32 +396,49 @@ assert(!MRI->isReserved(PhysReg) && "Reserved register assignment"); // Preserve semantics of sub-register operands. - if (MO.getSubReg()) { - // A virtual register kill refers to the whole register, so we may - // have to add operands for the super-register. A - // partial redef always kills and redefines the super-register. - if (NoSubRegLiveness && MO.readsReg() - && (MO.isDef() || MO.isKill())) - SuperKills.push_back(PhysReg); - - if (MO.isDef()) { - // The flag only makes sense for sub-register defs, and - // we are substituting a full physreg. An operand - // from the SuperKills list will represent the partial read of the - // super-register. - MO.setIsUndef(false); + unsigned SubReg = MO.getSubReg(); + if (SubReg != 0) { + if (NoSubRegLiveness) { + // A virtual register kill refers to the whole register, so we may + // have to add operands for the super-register. A + // partial redef always kills and redefines the super-register. + if (MO.readsReg() && (MO.isDef() || MO.isKill())) + SuperKills.push_back(PhysReg); // Also add implicit defs for the super-register. - if (NoSubRegLiveness) { - if (MO.isDead()) - SuperDeads.push_back(PhysReg); - else + if (MO.isDead()) + SuperDeads.push_back(PhysReg); + else + SuperDefs.push_back(PhysReg); + } else { + if (MO.isUse()) { + if (readsUndefSubreg(MO)) + // We need to add an flag if the subregister is + // completely undefined (and we are not adding super-register + // defs). + MO.setIsUndef(true); + } else if (!MO.isDead()) { + assert(MO.isDef()); + // Things get tricky when we ran out of lane mask bits and + // merged multiple lanes into the overflow bit: In this case + // our subregister liveness tracking isn't precise and we can't + // know what subregister parts are undefined, fall back to the + // implicit super-register def then. + unsigned LaneMask = TRI->getSubRegIndexLaneMask(SubReg); + if (TargetRegisterInfo::isImpreciseLaneMask(LaneMask)) SuperDefs.push_back(PhysReg); } } + // The flag only makes sense for sub-register defs, and + // we are substituting a full physreg. An operand + // from the SuperKills list will represent the partial read of the + // super-register. + if (MO.isDef()) + MO.setIsUndef(false); + // PhysReg operands cannot have subregister indexes. - PhysReg = TRI->getSubReg(PhysReg, MO.getSubReg()); + PhysReg = TRI->getSubReg(PhysReg, SubReg); assert(PhysReg && "Invalid SubReg for physical register"); MO.setSubReg(0); }