[PATCH] D70508: Fix an offset underflow bug in DwarfExpression when describing small values with subregisters

Adrian Prantl via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 20 13:14:48 PST 2019


aprantl created this revision.
aprantl added reviewers: vsk, bjope, dstenb, markus.
aprantl added a project: debug-info.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.

DwarfExpression::addMachineReg() knows how to build a larger register that isn't expressible in DWARF by combining multiple subregisters. However, if the entire value fits into just one subregister, it would still emit the other subregisters, leading to all sorts of inconsistencies down the line.

This patch fixes that by moving an already existing(!) check whether the subregister's offset is before the end of the value to the right place.


https://reviews.llvm.org/D70508

Files:
  llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
  llvm/test/DebugInfo/MIR/ARM/larger-subregister.mir


Index: llvm/test/DebugInfo/MIR/ARM/larger-subregister.mir
===================================================================
--- /dev/null
+++ llvm/test/DebugInfo/MIR/ARM/larger-subregister.mir
@@ -0,0 +1,36 @@
+# RUN: llc -start-before=livedebugvalues -filetype=obj -o - %s | \
+# RUN:     llvm-dwarfdump -debug-info - | FileCheck %s
+#
+# In this test the first DBG_VALUE is 32 bits large and sits in 128-bit register Q8,
+# which has to be decomposed into two 64-bit register D16, D17.
+# This test ensures that the unused D17 is suppressed in the output.
+#
+# CHECK: .debug_info contents:
+# CHECK: DW_TAG_formal_parameter
+# CHECK-NEXT: DW_AT_location
+# CHECK-NEXT: DW_OP_regx D16, DW_OP_piece 0x4, DW_OP_regx D15, DW_OP_bit_piece 0x20 0x20
+# CHECK-NEXT: DW_AT_name {{.*}}"boundingRect"
+--- |
+  target triple = "thumbv7k-apple-watchos"
+  define swiftcc void @f() !dbg !5 {
+       ret void
+  }
+  !llvm.module.flags = !{!0}
+  !llvm.dbg.cu = !{!2}
+  !0 = !{i32 2, !"Debug Info Version", i32 3}
+  !2 = distinct !DICompileUnit(language: DW_LANG_Swift, file: !3,
+  isOptimized: true, runtimeVersion: 5, emissionKind: FullDebug, enums: !4, globals: !4, imports: !4)
+  !3 = !DIFile(filename: "t.swift", directory: "/")
+  !4 = !{}
+  !5 = distinct !DISubprogram(name: "f", scope: !3, file: !3, line: 388, type: !9, scopeLine: 388, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4)
+  !9 = !DISubroutineType(types: !4)
+  !10 = !DILocation(line: 0, scope: !5)
+  !12 = !DILocalVariable(name: "boundingRect", arg: 1, scope: !5, file: !3, line: 388, type: !13)
+  !13 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !14)
+  !14 = !DICompositeType(tag: DW_TAG_structure_type, name: "CGRect", scope: !5, file: !3, line: 46, size: 128, elements: !4, runtimeLang: DW_LANG_Swift, identifier: "$sSo6CGRectVD")
+name:            'f'
+body:             |
+  bb.0:
+    DBG_VALUE $s31, $noreg, !12, !DIExpression(DW_OP_LLVM_fragment, 32, 32), debug-location !10
+    DBG_VALUE $q8, $noreg, !12, !DIExpression(DW_OP_LLVM_fragment, 0, 32), debug-location !10
+    renamable $r0 = t2ADDri $r6, 144, 14, $noreg, $noreg, debug-location !10
Index: llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -155,20 +155,18 @@
     CurSubReg.set(Offset, Offset + Size);
 
     // If this sub-register has a DWARF number and we haven't covered
-    // its range, emit a DWARF piece for it.
-    if (CurSubReg.test(Coverage)) {
+    // its range, and its range covers the value, emit a DWARF piece for it.
+    if (Offset < MaxSize && CurSubReg.test(Coverage)) {
       // Emit a piece for any gap in the coverage.
       if (Offset > CurPos)
-        DwarfRegs.push_back({-1, Offset - CurPos, "no DWARF register encoding"});
+        DwarfRegs.push_back(
+            {-1, Offset - CurPos, "no DWARF register encoding"});
       DwarfRegs.push_back(
           {Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"});
-      if (Offset >= MaxSize)
-        break;
-
-      // Mark it as emitted.
-      Coverage.set(Offset, Offset + Size);
-      CurPos = Offset + Size;
     }
+    // Mark it as emitted.
+    Coverage.set(Offset, Offset + Size);
+    CurPos = Offset + Size;
   }
   // Failed to find any DWARF encoding.
   if (CurPos == 0)
@@ -391,6 +389,7 @@
       // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base
       // location.
       assert(OffsetInBits >= FragmentOffset && "fragment offset not added?");
+      assert(SizeInBits >= OffsetInBits - FragmentOffset && "size underflow");
 
       // If addMachineReg already emitted DW_OP_piece operations to represent
       // a super-register by splicing together sub-registers, subtract the size


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D70508.230320.patch
Type: text/x-patch
Size: 3875 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191120/d07ad4e8/attachment.bin>


More information about the llvm-commits mailing list