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 @@ -1049,12 +1049,17 @@ // 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; + if (LI.hasSubRanges()) { + unsigned SubReg = MO.getSubReg(); + LaneBitmask LaneMask = SubReg ? TRI.getSubRegIndexLaneMask(SubReg) + : MRI.getMaxLaneMaskForVReg(Reg); + for (LiveInterval::SubRange &S : LI.subranges()) { + if ((S.LaneMask & LaneMask).none() || LI.covers(S)) + continue; + LI.clear(); + LIS.constructMainRangeFromSubranges(LI); + break; + } } continue; 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 @@ -532,6 +532,19 @@ }); } +TEST(LiveIntervalTest, TestMoveSubRegsOfOneReg) { + liveIntervalTest(R"MIR( + INLINEASM &"", 0, 1835018, def undef %4.sub0:vreg_64, 1835018, def undef %4.sub1:vreg_64 + %1:vreg_64 = COPY %4 + undef %2.sub0:vreg_64 = V_MOV_B32_e32 0, implicit $exec + %2.sub1:vreg_64 = COPY %2.sub0 + %3:vreg_64 = COPY %2 +)MIR", [](MachineFunction &MF, LiveIntervals &LIS) { + testHandleMove(MF, LIS, 1, 4); + testHandleMove(MF, LIS, 0, 3); + }); +} + TEST(LiveIntervalTest, BundleUse) { liveIntervalTest(R"MIR( %0 = IMPLICIT_DEF