Index: lib/CodeGen/LiveIntervalAnalysis.cpp =================================================================== --- lib/CodeGen/LiveIntervalAnalysis.cpp +++ lib/CodeGen/LiveIntervalAnalysis.cpp @@ -982,10 +982,38 @@ handleMoveDown(LR); else handleMoveUp(LR, Reg, LaneMask); + + // Fix liveins to other blocks which may need to be changed to new liveouts. + updateSuccessors(LR, LIS.getSlotIndexes()->getMBBFromIndex(NewIdx)); + DEBUG(dbgs() << " -->\t" << LR << '\n'); LR.verify(); } + // Update value numbers in successor blocks in case if we have a new liveout + // replacing an old one. I.e. if we have swapped two instructions defining + // subregisters of a same register. Last one becomes a new liveout. + // Only update Valno if supplied. + void updateSuccessors(LiveRange &LR, const MachineBasicBlock *MBB, + VNInfo *Valno = nullptr) { + VNInfo *Out = LR.getVNInfoBefore(LIS.getMBBEndIdx(MBB)); + if (!Out || (Valno && Out != Valno)) + return; + // This is a liveout. + // Find live-ins to other blocks which should connect to this live-out. + for (const auto &Succ : MBB->successors()) { + // Now set new value number in a successor. + auto *InSeg = LR.getSegmentContaining(LIS.getMBBStartIdx(Succ)); + if (InSeg && !InSeg->valno->isPHIDef() && InSeg->valno != Out) { + InSeg->valno = Out; + // Iterate next successors. No need to maintain visited list because + // when we update all possible segments loop will terminate. + if (InSeg->contains(LIS.getMBBEndIdx(Succ).getPrevSlot())) + updateSuccessors(LR, Succ, Out); + } + } + } + /// Update LR to reflect an instruction has been moved downwards from OldIdx /// to NewIdx (OldIdx < NewIdx). void handleMoveDown(LiveRange &LR) {