diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp --- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -590,6 +590,7 @@ bool TwoAddressInstructionPass::convertInstTo3Addr( MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, Register RegA, Register RegB, unsigned Dist) { + MachineInstrSpan MIS(mi, MBB); MachineInstr *NewMI = TII->convertToThreeAddress(*mi, LV); if (!NewMI) return false; @@ -597,9 +598,6 @@ LLVM_DEBUG(dbgs() << "2addr: CONVERTING 2-ADDR: " << *mi); LLVM_DEBUG(dbgs() << "2addr: TO 3-ADDR: " << *NewMI); - if (LIS) - LIS->ReplaceMachineInstrInMaps(*mi, *NewMI); - // If the old instruction is debug value tracked, an update is required. if (auto OldInstrNum = mi->peekDebugInstrNum()) { // Sanity check. @@ -618,8 +616,26 @@ std::make_pair(NewInstrNum, NewIdx)); } + // If convertToThreeAddress created a single new instruction, assume it has + // exactly the same effect on liveness as the old instruction. This is much + // more efficient than calling repairIntervalsInRange. + bool SingleInst = std::next(MIS.begin(), 2) == MIS.end(); + if (LIS && SingleInst) + LIS->ReplaceMachineInstrInMaps(*mi, *NewMI); + + SmallVector OrigRegs; + if (LIS && !SingleInst) { + for (const MachineOperand &MO : mi->operands()) { + if (MO.isReg()) + OrigRegs.push_back(MO.getReg()); + } + } + MBB->erase(mi); // Nuke the old inst. + if (LIS && !SingleInst) + LIS->repairIntervalsInRange(MBB, MIS.begin(), MIS.end(), OrigRegs); + DistanceMap.insert(std::make_pair(NewMI, Dist)); mi = NewMI; nmi = std::next(mi); diff --git a/llvm/test/CodeGen/X86/zext-trunc.ll b/llvm/test/CodeGen/X86/zext-trunc.ll --- a/llvm/test/CodeGen/X86/zext-trunc.ll +++ b/llvm/test/CodeGen/X86/zext-trunc.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -early-live-intervals -verify-machineinstrs | FileCheck %s ; rdar://7570931 define i64 @foo(i64 %a, i64 %b) nounwind {