[llvm] r323644 - [DebugInfo] Fix fragment offset emission order for symbol locations

Mikael Holmen via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 29 04:37:30 PST 2018


Author: uabelho
Date: Mon Jan 29 04:37:30 2018
New Revision: 323644

URL: http://llvm.org/viewvc/llvm-project?rev=323644&view=rev
Log:
[DebugInfo] Fix fragment offset emission order for symbol locations

Summary:
When emitting the location for a global variable with fragmented debug
expressions, make sure that the offset pieces, which represent
optimized-out parts of the variable, are emitted before their succeeding
fragments' expressions. Previously, if the succeeding fragment's
location was a symbol, the offset piece was emitted after, rather than
before, that symbol's expression. This effectively meant that the symbols
were associated with the wrong parts of the variable.

This fixes PR36085.

Patch by: David Stenberg

Reviewers: aprantl, probinson, dblaikie

Reviewed By: aprantl

Subscribers: JDevlieghere, llvm-commits

Tags: #debug-info

Differential Revision: https://reviews.llvm.org/D42527

Added:
    llvm/trunk/test/DebugInfo/X86/fragment-offset-order.ll
Modified:
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp?rev=323644&r1=323643&r2=323644&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Mon Jan 29 04:37:30 2018
@@ -191,6 +191,9 @@ DIE *DwarfCompileUnit::getOrCreateGlobal
       DwarfExpr = llvm::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc);
     }
 
+    if (Expr)
+      DwarfExpr->addFragmentOffset(Expr);
+
     if (Global) {
       const MCSymbol *Sym = Asm->getSymbol(Global);
       if (Global->isThreadLocal()) {
@@ -226,10 +229,8 @@ DIE *DwarfCompileUnit::getOrCreateGlobal
         addOpAddress(*Loc, Sym);
       }
     }
-    if (Expr) {
-      DwarfExpr->addFragmentOffset(Expr);
+    if (Expr)
       DwarfExpr->addExpression(Expr);
-    }
   }
   if (Loc)
     addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());

Added: llvm/trunk/test/DebugInfo/X86/fragment-offset-order.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/fragment-offset-order.ll?rev=323644&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/fragment-offset-order.ll (added)
+++ llvm/trunk/test/DebugInfo/X86/fragment-offset-order.ll Mon Jan 29 04:37:30 2018
@@ -0,0 +1,62 @@
+; RUN: llc -dwarf-version=4 -filetype=obj -O0 \
+; RUN:     -mtriple=x86_64-unknown-linux-gnu < %s \
+; RUN:     | llvm-dwarfdump -v - | FileCheck %s
+
+; Verify that the empty DW_OP_piece operations that are created for the
+; optimized-out struct fields `foo' and `baz' are emitted before their
+; succeeding fields' symbol location expressions.
+
+; Test file based on foo.c:
+;
+; struct {
+;   long foo;
+;   void *bar;
+;   long baz;
+;   void *qux;
+; } static var;
+; 
+; void *ptr;
+; 
+; int main() {
+;   if (var.foo == 0)
+;     var.bar = var.qux = ptr;
+;   return 0;
+; }
+;
+; which was built using:
+;
+; clang -O0 -g2 -S -emit-llvm foo.c -o foo.ll
+; opt -S -globalopt foo.ll -o foo.opt.ll
+
+; CHECK: DW_AT_name {{.*}}"var"
+; CHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_piece 0x8, DW_OP_addr 0x0, DW_OP_piece 0x8, DW_OP_piece 0x8, DW_OP_addr 0x0, DW_OP_piece 0x8)
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+ at var.1 = internal unnamed_addr global i8* null, align 8, !dbg !0
+ at var.3 = internal unnamed_addr global i8* null, align 8, !dbg !15
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!16, !17}
+!llvm.ident = !{!18}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression(DW_OP_LLVM_fragment, 64, 64))
+!1 = distinct !DIGlobalVariable(name: "var", scope: !2, file: !3, line: 15, type: !7, isLocal: true, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 7.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
+!3 = !DIFile(filename: "foo.c", directory: "/")
+!4 = !{}
+!5 = !{!6}
+!6 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !3, line: 10, size: 256, elements: !8)
+!8 = !{!9, !11, !13, !14}
+!9 = !DIDerivedType(tag: DW_TAG_member, name: "foo", scope: !7, file: !3, line: 11, baseType: !10, size: 64)
+!10 = !DIBasicType(name: "long int", size: 64, encoding: DW_ATE_signed)
+!11 = !DIDerivedType(tag: DW_TAG_member, name: "bar", scope: !7, file: !3, line: 12, baseType: !12, size: 64, offset: 64)
+!12 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
+!13 = !DIDerivedType(tag: DW_TAG_member, name: "baz", scope: !7, file: !3, line: 13, baseType: !10, size: 64, offset: 128)
+!14 = !DIDerivedType(tag: DW_TAG_member, name: "qux", scope: !7, file: !3, line: 14, baseType: !12, size: 64, offset: 192)
+!15 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression(DW_OP_LLVM_fragment, 192, 64))
+!16 = !{i32 2, !"Dwarf Version", i32 4}
+!17 = !{i32 2, !"Debug Info Version", i32 3}
+!18 = !{!"clang version 7.0.0"}




More information about the llvm-commits mailing list