Index: llvm/lib/CodeGen/LiveIntervals.cpp =================================================================== --- llvm/lib/CodeGen/LiveIntervals.cpp +++ llvm/lib/CodeGen/LiveIntervals.cpp @@ -1011,6 +1011,20 @@ } } updateRange(LI, Reg, LaneBitmask::getNone()); + // If main range has a hole and we are moving a subrange use across + // the hole updateRange() cannot properly handle it since it only + // gets the LiveRange and not the whole LiveInterval. As a result + // we may end up with a main range not covering all subranges. + // This is extremely rare case, so let's check and reconstruct the + // main range. + for (LiveInterval::SubRange &S : LI.subranges()) { + if (LI.covers(S)) + continue; + LI.clear(); + LIS.constructMainRangeFromSubranges(LI); + break; + } + continue; } Index: llvm/unittests/MI/LiveIntervalTest.cpp =================================================================== --- llvm/unittests/MI/LiveIntervalTest.cpp +++ llvm/unittests/MI/LiveIntervalTest.cpp @@ -499,6 +499,26 @@ }); } +TEST(LiveIntervalTest, TestMoveSubRegUseAcrossMainRangeHole) { + liveIntervalTest(R"MIR( + %1:sgpr_128 = IMPLICIT_DEF + bb.1: + %2:sgpr_32 = COPY %1.sub2 + %3:sgpr_32 = COPY %1.sub1 + %1.sub2 = COPY %2 + undef %1.sub0 = IMPLICIT_DEF + %1.sub2 = IMPLICIT_DEF + S_CBRANCH_SCC1 %bb.1, implicit undef $scc + S_BRANCH %bb.2 + bb.2: +)MIR", [](MachineFunction &MF, LiveIntervals &LIS) { + MachineInstr &MI = getMI(MF, 3, /*BlockNum=*/1); + MI.getOperand(0).setIsUndef(false); + testHandleMove(MF, LIS, 4, 3, 1); + testHandleMove(MF, LIS, 1, 4, 1); + }); +} + TEST(LiveIntervalTest, BundleUse) { liveIntervalTest(R"MIR( %0 = IMPLICIT_DEF