Index: lib/Target/X86/X86OptimizeLEAs.cpp =================================================================== --- lib/Target/X86/X86OptimizeLEAs.cpp +++ lib/Target/X86/X86OptimizeLEAs.cpp @@ -27,6 +27,7 @@ #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/Function.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -389,9 +390,6 @@ assert(isLEA(First) && isLEA(Last) && "The function works only with LEA instructions"); - // Get new address displacement. - AddrDispShift = getAddrDispShift(Last, 1, First, 1); - // Make sure that LEA def registers belong to the same class. There may be // instructions (like MOV8mr_NOREX) which allow a limited set of registers to // be used as their operands, so we must be sure that replacing one LEA @@ -400,10 +398,13 @@ MRI->getRegClass(Last.getOperand(0).getReg())) return false; + // Get new address displacement. + AddrDispShift = getAddrDispShift(Last, 1, First, 1); + // Loop over all uses of the Last LEA to check that its def register is // used only as address base for memory accesses. If so, it can be // replaced, otherwise - no. - for (auto &MO : MRI->use_operands(Last.getOperand(0).getReg())) { + for (auto &MO : MRI->use_nodbg_operands(Last.getOperand(0).getReg())) { MachineInstr &MI = *MO.getParent(); // Get the number of the first memory operand. @@ -532,6 +533,38 @@ return Changed; } +// Replace debug value MI with a new debug value instruction using register VReg +// and a new DIExpression based on the old DIExpression with the prepended +// address displacement. +static MachineInstr *replaceDebugValue(MachineInstr &MI, unsigned VReg, + int64_t AddrDispShift, + const X86InstrInfo *TII) { + // Get existing DIExpression elements and prepend address displacement. + const DIExpression *Expr = MI.getDebugExpression(); + ArrayRef OrigElements = Expr->getElements(); + SmallVector Elements(OrigElements.size() + 2); + if (AddrDispShift < 0) { + Elements[0] = dwarf::DW_OP_minus; + Elements[1] = -AddrDispShift; + } else { + Elements[0] = dwarf::DW_OP_plus; + Elements[1] = AddrDispShift; + } + std::copy(OrigElements.begin(), OrigElements.end(), Elements.begin() + 2); + + // Create new DIEXpression with address displacement. + Expr = DIExpression::get(Expr->getContext(), Elements); + + // Replace DBG_VALUE instruction with modified version. + MachineBasicBlock *MBB = MI.getParent(); + DebugLoc DL = MI.getDebugLoc(); + bool IsIndirect = MI.isIndirectDebugValue(); + uint64_t Offset = IsIndirect ? MI.getOperand(1).getImm() : 0; + const MDNode *Var = MI.getDebugVariable(); + return BuildMI(*MBB, MBB->erase(&MI), DL, TII->get(TargetOpcode::DBG_VALUE), + IsIndirect, VReg, Offset, Var, Expr); +} + // Try to find similar LEAs in the list and replace one with another. bool OptimizeLEAPass::removeRedundantLEAs(MemOpMap &LEAs) { bool Changed = false; @@ -563,12 +596,21 @@ // Loop over all uses of the Last LEA and update their operands. Note // that the correctness of this has already been checked in the // isReplaceable function. + const unsigned FirstVReg = First.getOperand(0).getReg(); for (auto UI = MRI->use_begin(Last.getOperand(0).getReg()), UE = MRI->use_end(); UI != UE;) { MachineOperand &MO = *UI++; MachineInstr &MI = *MO.getParent(); + if (MI.isDebugValue()) { + // Replace DBG_VALUE instruction with modified version using the + // register from the replacing LEA and the address displacement + // between the LEA instructions. + replaceDebugValue(MI, FirstVReg, AddrDispShift, TII); + continue; + } + // Get the number of the first memory operand. const MCInstrDesc &Desc = MI.getDesc(); int MemOpNo = @@ -576,7 +618,7 @@ X86II::getOperandBias(Desc); // Update address base. - MO.setReg(First.getOperand(0).getReg()); + MO.setReg(FirstVReg); // Update address disp. MachineOperand &Op = MI.getOperand(MemOpNo + X86::AddrDisp); @@ -587,14 +629,14 @@ } // Since we can possibly extend register lifetime, clear kill flags. - MRI->clearKillFlags(First.getOperand(0).getReg()); + MRI->clearKillFlags(FirstVReg); ++NumRedundantLEAs; DEBUG(dbgs() << "OptimizeLEAs: Remove redundant LEA: "; Last.dump();); // By this moment, all of the Last LEA's uses must be replaced. So we // can freely remove it. - assert(MRI->use_empty(Last.getOperand(0).getReg()) && + assert(MRI->use_nodbg_empty(Last.getOperand(0).getReg()) && "The LEA's def register must have no uses"); Last.eraseFromParent(); Index: test/CodeGen/X86/lea-opt-with-debug.mir =================================================================== --- /dev/null +++ test/CodeGen/X86/lea-opt-with-debug.mir @@ -0,0 +1,125 @@ +# RUN: llc -mtriple=x86_64-unknown-unknown -start-after peephole-opt -stop-before detect-dead-lanes -o - %s | FileCheck %s + +# Test that the optimize LEA pass can remove a redundant LEA even when it is +# also used by a DBG_VALUE. Check that the uses of the replaced LEA are updated +# correctly. + +--- | + target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" + + %struct.A = type { i32, i32, i32 } + + @c = common local_unnamed_addr global %struct.A* null, align 8 + @a = common local_unnamed_addr global i32 0, align 4 + @d = common local_unnamed_addr global i32 0, align 4 + @b = common local_unnamed_addr global i32 0, align 4 + + define i32 @fn1() local_unnamed_addr !dbg !9 { + %1 = load %struct.A*, %struct.A** @c, align 8, !dbg !14 + %2 = load i32, i32* @a, align 4, !dbg !14 + %3 = sext i32 %2 to i64, !dbg !14 + %4 = getelementptr inbounds %struct.A, %struct.A* %1, i64 %3, !dbg !14 + %5 = ptrtoint %struct.A* %4 to i64, !dbg !14 + %6 = trunc i64 %5 to i32, !dbg !14 + store i32 %6, i32* @d, align 4, !dbg !14 + %7 = getelementptr inbounds %struct.A, %struct.A* %1, i64 %3, i32 2, !dbg !15 + tail call void @llvm.dbg.value(metadata i32* %7, i64 0, metadata !12, metadata !16), !dbg !17 + br label %8, !dbg !18 + + ;