Index: lib/CodeGen/LiveIntervalAnalysis.cpp =================================================================== --- lib/CodeGen/LiveIntervalAnalysis.cpp +++ lib/CodeGen/LiveIntervalAnalysis.cpp @@ -388,9 +388,11 @@ if (!LiveOut.insert(Pred).second) continue; SlotIndex Stop = Indexes.getMBBEndIdx(Pred); - assert(OldRange.getVNInfoBefore(Stop) == VNI && - "Wrong value out of predecessor"); - WorkList.push_back(std::make_pair(Stop, VNI)); + // The exit from a predecessor may be jointly dominated by undefs. + if (VNInfo *PVNI = OldRange.getVNInfoBefore(Stop)) { + assert(PVNI == VNI && "Wrong value out of predecessor"); + WorkList.push_back(std::make_pair(Stop, PVNI)); + } } } } Index: lib/CodeGen/SplitKit.h =================================================================== --- lib/CodeGen/SplitKit.h +++ lib/CodeGen/SplitKit.h @@ -386,10 +386,14 @@ /// Return true if any ranges were skipped. bool transferValues(); - /// Live range @p LR has a live PHI def at the beginning of block @p B. - /// Extend the range @p LR of all predecessor values that reach this def. + /// Live range @p LR corresponding to the lane Mask @p LM has a live + /// PHI def at the beginning of block @p B. Extend the range @p LR of + /// all predecessor values that reach this def. If @p LR is a subrange, + /// the array @p Undefs is the set of all locations where it is undefined + /// via in other subranges for the same register. void extendPHIRange(MachineBasicBlock &B, LiveRangeCalc &LRC, - LiveRange &LR, ArrayRef); + LiveRange &LR, LaneBitmask LM, + ArrayRef Undefs); /// extendPHIKillRanges - Extend the ranges of all values killed by original /// parent PHIDefs. Index: lib/CodeGen/SplitKit.cpp =================================================================== --- lib/CodeGen/SplitKit.cpp +++ lib/CodeGen/SplitKit.cpp @@ -1092,13 +1092,19 @@ } void SplitEditor::extendPHIRange(MachineBasicBlock &B, LiveRangeCalc &LRC, - LiveRange &LR, ArrayRef Undefs) { + LiveRange &LR, LaneBitmask LM, + ArrayRef Undefs) { for (MachineBasicBlock *P : B.predecessors()) { SlotIndex End = LIS.getMBBEndIdx(P); SlotIndex LastUse = End.getPrevSlot(); // The predecessor may not have a live-out value. That is OK, like an // undef PHI operand. - if (Edit->getParent().liveAt(LastUse)) + LiveInterval &PLI = Edit->getParent(); + // Need the cast because the inputs to ?: would otherwise be deemed + // "incompatible": SubRange vs LiveInterval. + LiveRange &PSR = (LM != ~0u) ? getSubRangeForMask(LM, PLI) + : static_cast(PLI); + if (PSR.liveAt(LastUse)) LRC.extend(LR, End, /*PhysReg=*/0, Undefs); } } @@ -1120,7 +1126,7 @@ LiveRangeCalc &LRC = getLRCalc(RegIdx); MachineBasicBlock &B = *LIS.getMBBFromIndex(V->def); if (!removeDeadSegment(V->def, LI)) - extendPHIRange(B, LRC, LI, /*Undefs=*/{}); + extendPHIRange(B, LRC, LI, ~0u, /*Undefs=*/{}); } SmallVector Undefs; @@ -1141,7 +1147,7 @@ &LIS.getVNInfoAllocator()); Undefs.clear(); LI.computeSubRangeUndefs(Undefs, PS.LaneMask, MRI, *LIS.getSlotIndexes()); - extendPHIRange(B, SubLRC, S, Undefs); + extendPHIRange(B, SubLRC, S, PS.LaneMask, Undefs); } } }