Index: include/llvm/CodeGen/LiveRangeEdit.h =================================================================== --- include/llvm/CodeGen/LiveRangeEdit.h +++ include/llvm/CodeGen/LiveRangeEdit.h @@ -231,6 +231,8 @@ DeadRemats->insert(inst); } + bool isDeadRematInstr(MachineInstr *inst) { return DeadRemats->count(inst); } + /// eraseVirtReg - Notify the delegate that Reg is no longer in use, and try /// to erase it from LIS. void eraseVirtReg(unsigned Reg); Index: lib/CodeGen/LiveRangeEdit.cpp =================================================================== --- lib/CodeGen/LiveRangeEdit.cpp +++ lib/CodeGen/LiveRangeEdit.cpp @@ -147,7 +147,23 @@ const TargetRegisterInfo &tri, bool Late) { assert(RM.OrigMI && "Invalid remat"); + // The dest operand of Inst in DeadRemats is set to Dead because it + // uses dummy register and MachineVerifier will check it. + // When inst in DeadRemats is used for remat, need to set the dest + // operand of the inst not to be Dead before reMaterialize and reset + // it to be Dead after. That is because otherwise the flag will be + // copied to the remat instruction newly created in reMaterialize + // whose dest operand we know is not Dead. + bool isDeadRemat = isDeadRematInstr(RM.OrigMI); + if (isDeadRemat) + RM.OrigMI->getOperand(0).setIsDead(false); + + assert(!RM.OrigMI->getOperand(0).isDead() && + "dest register of OrigMI cannot be Dead before remat"); TII.reMaterialize(MBB, MI, DestReg, 0, RM.OrigMI, tri); + + if (isDeadRemat) + RM.OrigMI->getOperand(0).setIsDead(true); Rematted.insert(RM.ParentVNI); return LIS.getSlotIndexes() ->insertMachineInstrInMaps(*--MI, Late) @@ -325,12 +341,14 @@ // The inst is saved in LiveRangeEdit::DeadRemats and will be deleted // after all the allocations of the func are done. if (isOrigDef) { - unsigned NewDest = createFrom(Dest); + LiveInterval &NewLI = createEmptyIntervalFrom(Dest); + VNInfo *VNI = NewLI.getNextValue(Idx, LIS.getVNInfoAllocator()); + NewLI.addSegment(LiveInterval::Segment(Idx, Idx.getDeadSlot(), VNI)); pop_back(); markDeadRemat(MI); const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); - MI->substituteRegister(Dest, NewDest, 0, TRI); - MI->getOperand(0).setIsDead(false); + MI->substituteRegister(Dest, NewLI.reg, 0, TRI); + MI->getOperand(0).setIsDead(true); } else { if (TheDelegate) TheDelegate->LRE_WillEraseInstruction(MI); Index: test/CodeGen/X86/new-remat.ll =================================================================== --- test/CodeGen/X86/new-remat.ll +++ test/CodeGen/X86/new-remat.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s | FileCheck %s +; RUN: llc -verify-regalloc < %s | FileCheck %s ; Check all spills are rematerialized. ; CHECK-NOT: Spill