From 26b9b438fdda2dbfe8e37005cb33f5dc6b9c5e19 Mon Sep 17 00:00:00 2001 From: Andrea Di Biagio Date: Tue, 21 Mar 2017 11:36:21 +0000 Subject: [PATCH] [DebugInfo][X86] Teach Optimize LEAs pass to handle debug values This patch fixes an issue in the Optimize LEAs pass where redundant LEAs were not removed because they were being used by debug values. The debug values are now ignored when determining whether LEAs are redundant. For now the debug values for the redundant LEAs are marked as undefined, effectively lost. The intention is for a follow up patch which will attempt to preserve the debug values where possible. Patch by Andrew Ng. Differential Revision: https://reviews.llvm.org/D30835 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298360 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86OptimizeLEAs.cpp | 18 +++-- test/CodeGen/X86/lea-opt-with-debug.mir | 122 ++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 test/CodeGen/X86/lea-opt-with-debug.mir diff --git a/lib/Target/X86/X86OptimizeLEAs.cpp b/lib/Target/X86/X86OptimizeLEAs.cpp index e1447006cd1..debb192732e 100644 --- a/lib/Target/X86/X86OptimizeLEAs.cpp +++ b/lib/Target/X86/X86OptimizeLEAs.cpp @@ -389,9 +389,6 @@ bool OptimizeLEAPass::isReplaceable(const MachineInstr &First, 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 +397,13 @@ bool OptimizeLEAPass::isReplaceable(const MachineInstr &First, 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. @@ -563,8 +563,9 @@ bool OptimizeLEAPass::removeRedundantLEAs(MemOpMap &LEAs) { // 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. - for (auto UI = MRI->use_begin(Last.getOperand(0).getReg()), - UE = MRI->use_end(); + unsigned LastVReg = Last.getOperand(0).getReg(); + for (auto UI = MRI->use_nodbg_begin(LastVReg), + UE = MRI->use_nodbg_end(); UI != UE;) { MachineOperand &MO = *UI++; MachineInstr &MI = *MO.getParent(); @@ -586,6 +587,9 @@ bool OptimizeLEAPass::removeRedundantLEAs(MemOpMap &LEAs) { Op.setOffset(Op.getOffset() + AddrDispShift); } + // Mark debug values referring to Last LEA as undefined. + MRI->markUsesInDebugValueAsUndef(LastVReg); + // Since we can possibly extend register lifetime, clear kill flags. MRI->clearKillFlags(First.getOperand(0).getReg()); @@ -594,7 +598,7 @@ bool OptimizeLEAPass::removeRedundantLEAs(MemOpMap &LEAs) { // 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_empty(LastVReg) && "The LEA's def register must have no uses"); Last.eraseFromParent(); diff --git a/test/CodeGen/X86/lea-opt-with-debug.mir b/test/CodeGen/X86/lea-opt-with-debug.mir new file mode 100644 index 00000000000..ebf86ff718d --- /dev/null +++ b/test/CodeGen/X86/lea-opt-with-debug.mir @@ -0,0 +1,122 @@ +# RUN: llc -mtriple=x86_64-unknown-unknown -start-after peephole-opt -stop-before detect-dead-lanes -o - %s | FileCheck %s + +# Test that pass optimize LEA can remove a redundant LEA even when it is also +# used by a DBG_VALUE. + +--- | + target datalayout = "e-m:e-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 !8 { + %1 = load %struct.A*, %struct.A** @c, align 8, !dbg !13 + %2 = load i32, i32* @a, align 4, !dbg !13 + %3 = sext i32 %2 to i64, !dbg !13 + %4 = getelementptr inbounds %struct.A, %struct.A* %1, i64 %3, !dbg !13 + %5 = ptrtoint %struct.A* %4 to i64, !dbg !13 + %6 = trunc i64 %5 to i32, !dbg !13 + store i32 %6, i32* @d, align 4, !dbg !13 + %7 = getelementptr inbounds %struct.A, %struct.A* %1, i64 %3, i32 2, !dbg !14 + tail call void @llvm.dbg.value(metadata i32* %7, i64 0, metadata !11, metadata !15), !dbg !16 + br label %8, !dbg !17 + + ;