diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp --- a/llvm/lib/CodeGen/LiveIntervals.cpp +++ b/llvm/lib/CodeGen/LiveIntervals.cpp @@ -1342,7 +1342,7 @@ OldIdxOut->start = NewIdxDef; OldIdxVNI->def = NewIdxDef; if (OldIdxIn != E && SlotIndex::isEarlierInstr(NewIdx, OldIdxIn->end)) - OldIdxIn->end = NewIdx.getRegSlot(); + OldIdxIn->end = NewIdxDef; } } else if (OldIdxIn != E && SlotIndex::isEarlierInstr(NewIdxOut->start, NewIdx) diff --git a/llvm/unittests/MI/LiveIntervalTest.cpp b/llvm/unittests/MI/LiveIntervalTest.cpp --- a/llvm/unittests/MI/LiveIntervalTest.cpp +++ b/llvm/unittests/MI/LiveIntervalTest.cpp @@ -443,6 +443,21 @@ }); } +TEST(LiveIntervalTest, EarlyClobberSubRegMoveUp) { + // handleMoveUp had a bug where moving an early-clobber subreg def into the + // middle of an earlier segment resulted in an invalid live range. + liveIntervalTest(R"MIR( + %5704:sreg_32 = IMPLICIT_DEF + %5706:sreg_32 = IMPLICIT_DEF + undef early-clobber %5709.sub0:sreg_64 = WWM %5704:sreg_32, implicit $exec + %5755:sreg_32 = S_FLBIT_I32_B32 %5709.sub0:sreg_64 + early-clobber %5709.sub1:sreg_64 = WWM %5706:sreg_32, implicit $exec + %5757:sreg_32 = S_FLBIT_I32_B32 %5709.sub1:sreg_64 +)MIR", [](MachineFunction &MF, LiveIntervals &LIS) { + testHandleMove(MF, LIS, 4, 3); + }); +} + TEST(LiveIntervalTest, TestMoveSubRegDefAcrossUseDef) { liveIntervalTest(R"MIR( %1:vreg_64 = IMPLICIT_DEF