From ffa4b4378e645ee7bdf6b3da7f54640252ebad6f Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Wed, 19 Apr 2017 23:42:25 +0000 Subject: [PATCH] Fix bug that caused DwarfExpression to drop DW_OP_deref from FI locations - introduced in r300522 and found via the Swift LLDB testsuite. The fix is to set the location kind to memory whenever an FrameIndex location is emitted. rdar://problem/31707602 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300793 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 14 ++++++--- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 4 ++- lib/CodeGen/AsmPrinter/DwarfExpression.cpp | 8 ++--- lib/CodeGen/AsmPrinter/DwarfExpression.h | 16 ++++++---- lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 4 ++- test/DebugInfo/X86/fi-expr.ll | 35 +++++++++++++++++++++ 6 files changed, 62 insertions(+), 19 deletions(-) create mode 100644 test/DebugInfo/X86/fi-expr.ll diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 4a092ffbdc0..738e062cb93 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -556,9 +556,9 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, Ops.push_back(Offset); Ops.append(Expr->elements_begin(), Expr->elements_end()); DIExpressionCursor Cursor(Ops); - DwarfExpr.addMachineLocExpression( - *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, - MachineLocation(FrameReg)); + DwarfExpr.setMemoryLocationKind(); + DwarfExpr.addMachineRegExpression( + *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg); DwarfExpr.addExpression(std::move(Cursor)); } addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); @@ -780,6 +780,8 @@ void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, const MachineLocation &Location) { DIELoc *Loc = new (DIEValueAllocator) DIELoc; DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); + if (Location.isIndirect()) + DwarfExpr.setMemoryLocationKind(); SmallVector Ops; if (Location.isIndirect() && Location.getOffset()) { @@ -788,7 +790,7 @@ void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, } DIExpressionCursor Cursor(Ops); const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); - if (!DwarfExpr.addMachineLocExpression(TRI, Cursor, Location)) + if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) return; DwarfExpr.addExpression(std::move(Cursor)); @@ -807,6 +809,8 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); const DIExpression *DIExpr = DV.getSingleExpression(); DwarfExpr.addFragmentOffset(DIExpr); + if (Location.isIndirect()) + DwarfExpr.setMemoryLocationKind(); SmallVector Ops; if (Location.isIndirect() && Location.getOffset()) { @@ -816,7 +820,7 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, Ops.append(DIExpr->elements_begin(), DIExpr->elements_end()); DIExpressionCursor Cursor(Ops); const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); - if (!DwarfExpr.addMachineLocExpression(TRI, Cursor, Location)) + if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) return; DwarfExpr.addExpression(std::move(Cursor)); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index b5a99aa5545..d72656bcc58 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1517,6 +1517,8 @@ static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, DwarfExpr.addUnsignedConstant(Value.getInt()); } else if (Value.isLocation()) { MachineLocation Location = Value.getLoc(); + if (Location.isIndirect()) + DwarfExpr.setMemoryLocationKind(); SmallVector Ops; if (Location.isIndirect() && Location.getOffset()) { Ops.push_back(dwarf::DW_OP_plus); @@ -1525,7 +1527,7 @@ static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, Ops.append(DIExpr->elements_begin(), DIExpr->elements_end()); DIExpressionCursor Cursor(Ops); const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo(); - if (!DwarfExpr.addMachineLocExpression(TRI, Cursor, Location)) + if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) return; return DwarfExpr.addExpression(std::move(Cursor)); } else if (Value.isConstantFP()) { diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index d21288f4b81..55397c3ac09 100644 --- a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -193,14 +193,10 @@ void DwarfExpression::addUnsignedConstant(const APInt &Value) { } } -bool DwarfExpression::addMachineLocExpression(const TargetRegisterInfo &TRI, +bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &ExprCursor, - MachineLocation Loc, + unsigned MachineReg, unsigned FragmentOffsetInBits) { - if (Loc.isIndirect()) - LocationKind = Memory; - - unsigned MachineReg = Loc.getReg(); auto Fragment = ExprCursor.getFragmentInfo(); if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) return false; diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.h b/lib/CodeGen/AsmPrinter/DwarfExpression.h index 00734fd6843..203990dd3c9 100644 --- a/lib/CodeGen/AsmPrinter/DwarfExpression.h +++ b/lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -16,7 +16,6 @@ #include "llvm/IR/DebugInfo.h" #include "llvm/Support/DataTypes.h" -#include "llvm/MC/MachineLocation.h" namespace llvm { @@ -113,8 +112,6 @@ protected: SubRegisterOffsetInBits = OffsetInBits; } - void setMemoryLocationKind(); - /// Add masking operations to stencil out a subregister. void maskSubRegister(); @@ -192,17 +189,24 @@ public: /// Emit an unsigned constant. void addUnsignedConstant(const APInt &Value); + /// Lock this down to become a memory location description. + void setMemoryLocationKind() { + assert(LocationKind == Unknown); + LocationKind = Memory; + } + /// Emit a machine register location. As an optimization this may also consume /// the prefix of a DwarfExpression if a more efficient representation for /// combining the register location and the first operation exists. /// - /// \param FragmentOffsetInBits If this is one fragment out of a fragmented + /// \param FragmentOffsetInBits If this is one fragment out of a + /// fragmented /// location, this is the offset of the /// fragment inside the entire variable. /// \return false if no DWARF register exists /// for MachineReg. - bool addMachineLocExpression(const TargetRegisterInfo &TRI, - DIExpressionCursor &Expr, MachineLocation Loc, + bool addMachineRegExpression(const TargetRegisterInfo &TRI, + DIExpressionCursor &Expr, unsigned MachineReg, unsigned FragmentOffsetInBits = 0); /// Emit all remaining operations in the DIExpressionCursor. /// diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index f5dccd17295..bac0c204d04 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -472,6 +472,8 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die, // variable's location. DIELoc *Loc = new (DIEValueAllocator) DIELoc; DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); + if (Location.isIndirect()) + DwarfExpr.setMemoryLocationKind(); SmallVector Ops; if (Location.isIndirect() && Location.getOffset()) { @@ -505,7 +507,7 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die, DIExpressionCursor Cursor(Ops); const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); - if (!DwarfExpr.addMachineLocExpression(TRI, Cursor, Location)) + if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) return; DwarfExpr.addExpression(std::move(Cursor)); diff --git a/test/DebugInfo/X86/fi-expr.ll b/test/DebugInfo/X86/fi-expr.ll new file mode 100644 index 00000000000..cf240505c0c --- /dev/null +++ b/test/DebugInfo/X86/fi-expr.ll @@ -0,0 +1,35 @@ +; RUN: llc -mtriple=x86_64-apple-darwin -o - %s -filetype=obj \ +; RUN: | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; A hand-crafted FrameIndex location with a DW_OP_deref. +; CHECK: DW_TAG_formal_parameter +; fbreg -8, deref +; CHECK-NEXT: DW_AT_location {{.*}} (<0x3> 91 78 06 ) +; CHECK-NEXT: DW_AT_name {{.*}} "foo" +define void @f(i8* %bar) !dbg !6 { +entry: + %foo.addr = alloca i8* + store i8* %bar, i8** %foo.addr + call void @llvm.dbg.declare(metadata i8** %foo.addr, metadata !12, metadata !13), !dbg !14 + ret void, !dbg !15 +} + +declare void @llvm.dbg.declare(metadata, metadata, metadata) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "t.c", directory: "/") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!6 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!7 = !DISubroutineType(types: !8) +!8 = !{null, !9} +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64) +!10 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !11) +!11 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!12 = !DILocalVariable(name: "foo", arg: 1, scope: !6, file: !1, line: 1, type: !10) +!13 = !DIExpression(DW_OP_deref) +!14 = !DILocation(line: 1, scope: !6) +!15 = !DILocation(line: 1, scope: !6) -- 2.50.1