Index: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp =================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -1232,10 +1232,12 @@ LiveRange::iterator NewIdxIn = NewIdxOut; assert(NewIdxIn == LR.find(NewIdx.getBaseIndex())); const SlotIndex SplitPos = NewIdxDef; + OldIdxVNI = OldIdxIn->valno; // Merge the OldIdxIn and OldIdxOut segments into OldIdxOut. + OldIdxOut->valno->def = OldIdxIn->start; *OldIdxOut = LiveRange::Segment(OldIdxIn->start, OldIdxOut->end, - OldIdxIn->valno); + OldIdxOut->valno); // OldIdxIn and OldIdxVNI are now undef and can be overridden. // We Slide [NewIdxIn, OldIdxIn) down one position. // |- X0/NewIdxIn -| ... |- Xn-1 -||- Xn/OldIdxIn -||- OldIdxOut -| Index: llvm/trunk/unittests/MI/LiveIntervalTest.cpp =================================================================== --- llvm/trunk/unittests/MI/LiveIntervalTest.cpp +++ llvm/trunk/unittests/MI/LiveIntervalTest.cpp @@ -382,6 +382,24 @@ }); } +TEST(LiveIntervalTest, SubRegMoveUp) { + // handleMoveUp had a bug not updating valno of segment incoming to bb.2 + // after swapping subreg definitions. + liveIntervalTest(R"MIR( + successors: %bb.1, %bb.2 + undef %0.sub0 = IMPLICIT_DEF + %0.sub1 = IMPLICIT_DEF + S_CBRANCH_VCCNZ %bb.2, implicit undef %vcc + S_BRANCH %bb.1 + bb.1: + S_NOP 0, implicit %0.sub1 + bb.2: + S_NOP 0, implicit %0.sub1 +)MIR", [](MachineFunction &MF, LiveIntervals &LIS) { + testHandleMove(MF, LIS, 1, 0); + }); +} + int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); initLLVM();