Skip to content

Commit bc5dac1

Browse files
[AsmPrinter][DwarfDebug] Skip vars with fragments in different location kinds
The AsmPrinter currently assumes that a Debug Variable will have all of its fragments with the same "kind" of location (i.e. all in the stack or all in entry values). This is not enforced by the verifier, so it needs to be handled properly. Until we do so, we conservatively drop one of the fragments. Differential Revision: https://reviews.llvm.org/D159468
1 parent 08425de commit bc5dac1

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,12 +1546,27 @@ void DwarfDebug::collectVariableInfoFromMFTable(
15461546

15471547
ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first, Scope->getScopeNode());
15481548

1549-
if (DbgVariable *DbgVar = MFVars.lookup(Var)) {
1550-
if (auto *MMI = std::get_if<Loc::MMI>(DbgVar))
1551-
MMI->addFrameIndexExpr(VI.Expr, VI.getStackSlot());
1552-
else
1553-
DbgVar->get<Loc::EntryValue>().addExpr(VI.getEntryValueRegister(),
1554-
*VI.Expr);
1549+
// If we have already seen information for this variable, add to what we
1550+
// already know.
1551+
if (DbgVariable *PreviousLoc = MFVars.lookup(Var)) {
1552+
auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1553+
auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1554+
// Previous and new locations are both stack slots (MMI).
1555+
if (PreviousMMI && VI.inStackSlot())
1556+
PreviousMMI->addFrameIndexExpr(VI.Expr, VI.getStackSlot());
1557+
// Previous and new locations are both entry values.
1558+
else if (PreviousEntryValue && VI.inEntryValueRegister())
1559+
PreviousEntryValue->addExpr(VI.getEntryValueRegister(), *VI.Expr);
1560+
else {
1561+
// Locations differ, this should (rarely) happen in optimized async
1562+
// coroutines.
1563+
// Prefer whichever location has an EntryValue.
1564+
if (PreviousLoc->holds<Loc::MMI>())
1565+
PreviousLoc->emplace<Loc::EntryValue>(VI.getEntryValueRegister(),
1566+
*VI.Expr);
1567+
LLVM_DEBUG(dbgs() << "Dropping debug info for " << VI.Var->getName()
1568+
<< ", conflicting fragment location types\n");
1569+
}
15551570
continue;
15561571
}
15571572

llvm/test/DebugInfo/AArch64/dbg-entry-value-swiftasync.mir

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,23 @@
88
# CHECK-SAME: DW_OP_GNU_entry_value(DW_OP_reg22 W22), DW_OP_piece 0x8,
99
# CHECK-SAME: DW_OP_GNU_entry_value(DW_OP_reg22 W22), DW_OP_plus_uconst 0x2a, DW_OP_piece 0x8)
1010
# CHECK-NEXT: DW_AT_name ("fragmented_var")
11+
# CHECK: DW_TAG_variable
12+
# CHECK-NEXT: DW_AT_location (DW_OP_piece 0x8, DW_OP_GNU_entry_value(DW_OP_reg22 W22), DW_OP_piece 0x8)
13+
# CHECK-NEXT: DW_AT_name ("multi_type_fragmented_var")
1114

1215

1316
--- |
1417
target triple = "aarch64--"
1518
define void @foo(ptr %unused_arg, ptr swiftasync %async_arg) !dbg !4 {
19+
%storage = alloca i64
1620
call void @llvm.dbg.declare(metadata ptr %async_arg, metadata !10, metadata !DIExpression(DW_OP_LLVM_entry_value, 1)), !dbg !12
1721
; A two fragment variable.
1822
; Fragments intentionally out of order to ensure the code can handle this.
1923
call void @llvm.dbg.declare(metadata ptr %async_arg, metadata !10, metadata !DIExpression(DW_OP_LLVM_entry_value, 1, DW_OP_plus_uconst, 42, DW_OP_LLVM_fragment, 64, 64)), !dbg !12
2024
call void @llvm.dbg.declare(metadata ptr %async_arg, metadata !11, metadata !DIExpression(DW_OP_LLVM_entry_value, 1, DW_OP_LLVM_fragment, 0, 64)), !dbg !12
25+
; A fragmented variable mixing entry values and stack slot locations.
26+
call void @llvm.dbg.declare(metadata ptr %async_arg, metadata !13, metadata !DIExpression(DW_OP_LLVM_entry_value, 1, DW_OP_LLVM_fragment, 64, 64)), !dbg !12
27+
call void @llvm.dbg.declare(metadata ptr %storage, metadata !13, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64)), !dbg !12
2128
ret void, !dbg !12
2229
}
2330
declare void @llvm.dbg.declare(metadata, metadata, metadata)
@@ -36,6 +43,7 @@
3643
!10 = !DILocalVariable(name: "a", scope: !4, file: !1, line: 1, type: !7)
3744
!11 = !DILocalVariable(name: "fragmented_var", scope: !4, file: !1, line: 1, type: !7)
3845
!12 = !DILocation(line: 1, column: 37, scope: !4)
46+
!13 = !DILocalVariable(name: "multi_type_fragmented_var", scope: !4, file: !1, line: 1, type: !7)
3947
...
4048
---
4149
name: foo
@@ -45,13 +53,20 @@ liveins:
4553
stack:
4654
- { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
4755
stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true }
56+
- { id: 1, name: '', type: default, offset: 0, size: 1, alignment: 8,
57+
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
58+
debug-info-variable: '!13', debug-info-expression: '!DIExpression(DW_OP_LLVM_fragment, 0, 64)',
59+
debug-info-location: '!12' }
60+
4861
entry_values:
4962
- { entry-value-register: '$x22', debug-info-variable: '!10', debug-info-expression: '!DIExpression(DW_OP_LLVM_entry_value, 1, DW_OP_deref)',
5063
debug-info-location: '!12' }
5164
- { entry-value-register: '$x22', debug-info-variable: '!11', debug-info-expression: '!DIExpression(DW_OP_LLVM_entry_value, 1, DW_OP_plus_uconst, 42, DW_OP_deref, DW_OP_LLVM_fragment, 64, 64)',
5265
debug-info-location: '!12' }
5366
- { entry-value-register: '$x22', debug-info-variable: '!11', debug-info-expression: '!DIExpression(DW_OP_LLVM_entry_value, 1, DW_OP_deref, DW_OP_LLVM_fragment, 0, 64)',
5467
debug-info-location: '!12' }
68+
- { entry-value-register: '$x22', debug-info-variable: '!13', debug-info-expression: '!DIExpression(DW_OP_LLVM_entry_value, 1, DW_OP_deref, DW_OP_LLVM_fragment, 64, 64)',
69+
debug-info-location: '!12' }
5570
body: |
5671
bb.0 (%ir-block.0):
5772
liveins: $x0, $x22, $lr

0 commit comments

Comments
 (0)