diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp index b830c93d43f47d..2bbe036e8425a4 100644 --- a/llvm/lib/CodeGen/LiveIntervals.cpp +++ b/llvm/lib/CodeGen/LiveIntervals.cpp @@ -1342,7 +1342,7 @@ class LiveIntervals::HMEditor { 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 index ea8476db1e656b..5c974ea7461e48 100644 --- a/llvm/unittests/MI/LiveIntervalTest.cpp +++ b/llvm/unittests/MI/LiveIntervalTest.cpp @@ -443,6 +443,21 @@ TEST(LiveIntervalTest, DeadSubRegMoveUp) { }); } +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( + %4:sreg_32 = IMPLICIT_DEF + %6:sreg_32 = IMPLICIT_DEF + undef early-clobber %9.sub0:sreg_64 = WWM %4:sreg_32, implicit $exec + %5:sreg_32 = S_FLBIT_I32_B32 %9.sub0:sreg_64 + early-clobber %9.sub1:sreg_64 = WWM %6:sreg_32, implicit $exec + %7:sreg_32 = S_FLBIT_I32_B32 %9.sub1:sreg_64 +)MIR", [](MachineFunction &MF, LiveIntervals &LIS) { + testHandleMove(MF, LIS, 4, 3); + }); +} + TEST(LiveIntervalTest, TestMoveSubRegDefAcrossUseDef) { liveIntervalTest(R"MIR( %1:vreg_64 = IMPLICIT_DEF