Fix a fragment overflow problem when composing super-registers.
authorAdrian Prantl <aprantl@apple.com>
Thu, 27 Jan 2022 23:43:43 +0000 (15:43 -0800)
committerAdrian Prantl <aprantl@apple.com>
Mon, 31 Jan 2022 17:47:29 +0000 (09:47 -0800)
Addresses https://github.com/llvm/llvm-project/issues/53342

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

llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
llvm/test/DebugInfo/MIR/AArch64/subreg-fragment-overflow.mir [new file with mode: 0644]

index ee932d1..fe43810 100644 (file)
@@ -287,9 +287,17 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
   // expression representing a value, rather than a location.
   if ((!isParameterValue() && !isMemoryLocation() && !HasComplexExpression) ||
       isEntryValue()) {
+    auto FragmentInfo = ExprCursor.getFragmentInfo();
+    unsigned RegSize = 0;
     for (auto &Reg : DwarfRegs) {
+      RegSize += Reg.SubRegSize;
       if (Reg.DwarfRegNo >= 0)
         addReg(Reg.DwarfRegNo, Reg.Comment);
+      if (FragmentInfo)
+        if (RegSize > FragmentInfo->SizeInBits)
+          // If the register is larger than the current fragment stop
+          // once the fragment is covered.
+          break;
       addOpPiece(Reg.SubRegSize);
     }
 
diff --git a/llvm/test/DebugInfo/MIR/AArch64/subreg-fragment-overflow.mir b/llvm/test/DebugInfo/MIR/AArch64/subreg-fragment-overflow.mir
new file mode 100644 (file)
index 0000000..d0b1384
--- /dev/null
@@ -0,0 +1,34 @@
+# RUN: llc -mtriple aarch64-linux-gnu -start-after=livedebugvalues -filetype=obj -o - %s \
+# RUN:     | llvm-dwarfdump - | FileCheck %s
+# The value needs to be composed of sub-registers, but the
+# sub-registers cross the fragment boundary.
+# CHECK: DW_OP_piece 0x8, DW_OP_regx B16, DW_OP_piece 0x8
+--- |
+  target triple = "aarch64-none-linux-android21"
+  define linkonce_odr dso_local void @_f() !dbg !1590 {
+  entry:
+    ret void, !dbg !1809
+  }
+  declare i32 @__gxx_personality_v0(...)
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags =  !{!1586,!1587}
+  !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+  !1 = !DIFile(filename: "bug.cpp", directory: "/")
+  !1586 = !{i32 2, !"Debug Info Version", i32 3}
+  !1587 = !{i32 7, !"frame-pointer", i32 1}
+  !1590 = distinct !DISubprogram(name: "f", scope: !0, file: !1, line: 278, type: !1591, scopeLine: 279, flags: DIFlagPrototyped, unit: !0, declaration: !1593)
+  !1591 = !DISubroutineType(types: !1592)
+  !1592 = !{null  }
+  !1593 = !DISubprogram(name: "f", linkageName: "_f", scope: !0, file: !1, line: 195, type: !1591, scopeLine: 195, flags:
+  DIFlagProtected
+  , spFlags: DISPFlagOptimized)
+  !1694 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "uint8x8x3_t", file: !1, line: 235, size: 192, flags: DIFlagTypePassByValue, elements: !1695, identifier: "_ZTS11uint8x8x3_t")
+  !1695 = !{}
+  !1715 = !DILocalVariable(name: "__ret", scope: !1590, file: !1, line: 379, type: !1694)
+  !1809 = !DILocation(line: 0, scope: !1590   )
+---
+name:            _f
+body:             |
+  bb.0.entry:
+    renamable $d16_d17_d18 = LD3Threev8b killed renamable $x15, debug-location !1809
+    DBG_VALUE $d16_d17_d18, $noreg, !1715, !DIExpression(DW_OP_LLVM_fragment, 64, 64), debug-location !1809