[llvm] r335205 - [DebugInfo] Keep DBG_VALUE undef in LiveDebugVariables

Mikael Holmen via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 21 00:02:46 PDT 2018


Author: uabelho
Date: Thu Jun 21 00:02:46 2018
New Revision: 335205

URL: http://llvm.org/viewvc/llvm-project?rev=335205&view=rev
Log:
[DebugInfo] Keep DBG_VALUE undef in LiveDebugVariables

Summary:
Fixes PR36579.

For cases where we had e.g.

 DBG_VALUE 42
 [...]
 DBG_VALUE undef

LiveDebugVariables would discard all undef DBG_VALUEs and then it would
look like the variable had the value 42 throughout the rest of the
function, which is incorrect.

With this patch we don't remove all undef DBG_VALUEs in LiveDebugVariables
so they will be kept after register allocation just like other DBG_VALUEs
which will yield more correct debug information.

Reviewers: aprantl

Reviewed By: aprantl

Subscribers: bjope, Ka-Ka, JDevlieghere, llvm-commits

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

Added:
    llvm/trunk/test/DebugInfo/X86/live-debug-vars-keep-undef.ll
Modified:
    llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp
    llvm/trunk/test/DebugInfo/X86/live-debug-vars-discard-invalid.mir

Modified: llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp?rev=335205&r1=335204&r2=335205&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp Thu Jun 21 00:02:46 2018
@@ -224,7 +224,12 @@ public:
     return L1;
   }
 
-  /// getLocationNo - Return the location number that matches Loc.
+  /// Return the location number that matches Loc.
+  ///
+  /// For undef values we always return location number UndefLocNo without
+  /// inserting anything in locations. Since locations is a vector and the
+  /// location number is the position in the vector and UndefLocNo is ~0,
+  /// we would need a very big vector to put the value at the right position.
   unsigned getLocationNo(const MachineOperand &LocMO) {
     if (LocMO.isReg()) {
       if (LocMO.getReg() == 0)
@@ -761,13 +766,6 @@ void UserValue::computeIntervals(Machine
     // function).
   }
 
-  // Erase all the undefs.
-  for (LocMap::iterator I = locInts.begin(); I.valid();)
-    if (I.value().isUndef())
-      I.erase();
-    else
-      ++I;
-
   // The computed intervals may extend beyond the range of the debug
   // location's lexical scope. In this case, splitting of an interval
   // can result in an interval outside of the scope being created,
@@ -990,7 +988,9 @@ UserValue::splitLocation(unsigned OldLoc
                         << LocMapI.stop() << ")\n");
       LocMapI.erase();
     } else {
-      if (v.locNo() > OldLocNo)
+      // Undef values always have location number UndefLocNo, so don't change
+      // locNo in that case. See getLocationNo().
+      if (!v.isUndef() && v.locNo() > OldLocNo)
         LocMapI.setValueUnchecked(v.changeLocNo(v.locNo() - 1));
       ++LocMapI;
     }
@@ -1099,6 +1099,10 @@ void UserValue::rewriteLocations(VirtReg
   // physical register.
   for (LocMap::iterator I = locInts.begin(); I.valid(); ++I) {
     DbgValueLocation Loc = I.value();
+    // Undef values don't exist in locations (and thus not in LocNoMap either)
+    // so skip over them. See getLocationNo().
+    if (Loc.isUndef())
+      continue;
     unsigned NewLocNo = LocNoMap[Loc.locNo()];
     I.setValueUnchecked(Loc.changeLocNo(NewLocNo));
     I.setStart(I.start());
@@ -1163,7 +1167,15 @@ void UserValue::insertDebugValue(Machine
   // Only search within the current MBB.
   StopIdx = (MBBEndIdx < StopIdx) ? MBBEndIdx : StopIdx;
   MachineBasicBlock::iterator I = findInsertLocation(MBB, StartIdx, LIS);
-  MachineOperand &MO = locations[Loc.locNo()];
+  // Undef values don't exist in locations so create new "noreg" register MOs
+  // for them. See getLocationNo().
+  MachineOperand MO = !Loc.isUndef() ?
+    locations[Loc.locNo()] :
+    MachineOperand::CreateReg(/* Reg */ 0, /* isDef */ false, /* isImp */ false,
+                              /* isKill */ false, /* isDead */ false,
+                              /* isUndef */ false, /* isEarlyClobber */ false,
+                              /* SubReg */ 0, /* isDebug */ true);
+
   ++NumInsertedDebugValues;
 
   assert(cast<DILocalVariable>(Variable)

Modified: llvm/trunk/test/DebugInfo/X86/live-debug-vars-discard-invalid.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/live-debug-vars-discard-invalid.mir?rev=335205&r1=335204&r2=335205&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/live-debug-vars-discard-invalid.mir (original)
+++ llvm/trunk/test/DebugInfo/X86/live-debug-vars-discard-invalid.mir Thu Jun 21 00:02:46 2018
@@ -106,17 +106,11 @@ body:             |
 # CHECK-LABEL: name: foobar
 
 # CHECK-LABEL: bb.1:
-## After solving https://bugs.llvm.org/show_bug.cgi?id=36579 we expect to get a
-##   DBG_VALUE debug-use $noreg
-## here.
-# CHECK-NOT:    DBG_VALUE
+# CHECK:        DBG_VALUE debug-use $noreg
 
 # CHECK-LABEL: bb.2:
-## After solving https://bugs.llvm.org/show_bug.cgi?id=36579 we expect to get a
-##   DBG_VALUE debug-use $noreg
-## here.
-# CHECK-NOT:    DBG_VALUE
-# CHECK:        dead renamable $rcx = IMPLICIT_DEF
+# CHECK:        DBG_VALUE debug-use $noreg
+# CHECK-NEXT:   dead renamable $rcx = IMPLICIT_DEF
 # CHECK-NEXT:   dead renamable $rcx = IMPLICIT_DEF
 # CHECK-NEXT:   dead renamable $rcx = IMPLICIT_DEF
 # CHECK-NEXT:   dead renamable $rcx = IMPLICIT_DEF

Added: llvm/trunk/test/DebugInfo/X86/live-debug-vars-keep-undef.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/live-debug-vars-keep-undef.ll?rev=335205&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/live-debug-vars-keep-undef.ll (added)
+++ llvm/trunk/test/DebugInfo/X86/live-debug-vars-keep-undef.ll Thu Jun 21 00:02:46 2018
@@ -0,0 +1,65 @@
+; RUN: llc -O1 -o - %s | FileCheck %s
+
+; Check that dbg.value(undef) calls are not simply discarded.
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @foo() !dbg !7 {
+entry:
+  call void @llvm.dbg.value(metadata i32 42, metadata !11, metadata !DIExpression()), !dbg !13
+  call void (...) @bar(), !dbg !14
+  call void @llvm.dbg.value(metadata i32 undef, metadata !11, metadata !DIExpression()), !dbg !13
+  call void (...) @bar(), !dbg !15
+  ret void, !dbg !16
+}
+
+declare void @bar(...)
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.value(metadata, metadata, metadata) #0
+
+attributes #0 = { nounwind readnone speculatable }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 7.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "test.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 7.0.0"}
+!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, isOptimized: true, unit: !0, retainedNodes: !10)
+!8 = !DISubroutineType(types: !9)
+!9 = !{null}
+!10 = !{!11}
+!11 = !DILocalVariable(name: "x", scope: !7, file: !1, line: 4, type: !12)
+!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!13 = !DILocation(line: 4, column: 7, scope: !7)
+!14 = !DILocation(line: 5, column: 3, scope: !7)
+!15 = !DILocation(line: 7, column: 3, scope: !7)
+!16 = !DILocation(line: 8, column: 1, scope: !7)
+
+; Original C program:
+;  void bar();
+;
+;  void foo() {
+;    int x = 42;
+;    bar();
+;    x = 23;
+;    bar();
+;  }
+;
+; Then the dbg.value for the x = 23 setting has been replaced with dbg.value(undef)
+; in this ll file to provoke the wanted behavior in LiveDebugVariables.
+
+; Variable 'x' should thus be updated two times, first to 42 and then to undef.
+
+; CHECK-LABEL: foo:
+; CHECK:               #DEBUG_VALUE: foo:x <- 42
+; CHECK:               callq   bar
+; CHECK:               #DEBUG_VALUE: foo:x <- undef
+; CHECK:               callq   bar




More information about the llvm-commits mailing list