Skip to content

Commit 7f21e95

Browse files
author
git apple-llvm automerger
committed
Merge commit '32ef4ceec03d' from llvm.org/main into next
2 parents c14cfdd + 32ef4ce commit 7f21e95

File tree

4 files changed

+258
-5
lines changed

4 files changed

+258
-5
lines changed

llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ class TransferTracker {
363363
SmallVector<ResolvedDbgOp> ResolvedDbgOps;
364364
bool IsValueValid = true;
365365
unsigned LastUseBeforeDef = 0;
366+
bool DbgLocAvailableAndIsEntryVal = false;
366367

367368
// If every value used by the incoming DbgValue is available at block
368369
// entry, ResolvedDbgOps will contain the machine locations/constants for
@@ -416,6 +417,8 @@ class TransferTracker {
416417
// live range.
417418
LocIdx M = ValuesPreferredLoc->second.getLoc();
418419
ResolvedDbgOps.push_back(M);
420+
if (Value.Properties.DIExpr->isEntryValue())
421+
DbgLocAvailableAndIsEntryVal = true;
419422
}
420423

421424
// If we cannot produce a valid value for the LiveIn value within this
@@ -429,6 +432,16 @@ class TransferTracker {
429432
return;
430433
}
431434

435+
auto &[Var, DILoc] = DVMap.lookupDVID(VarID);
436+
PendingDbgValues.push_back(
437+
std::make_pair(VarID, &*MTracker->emitLoc(ResolvedDbgOps, Var, DILoc,
438+
Value.Properties)));
439+
440+
// If the location is available at block entry and is an entry value, skip
441+
// tracking and recording thr transfer.
442+
if (DbgLocAvailableAndIsEntryVal)
443+
return;
444+
432445
// The LiveIn value is available at block entry, begin tracking and record
433446
// the transfer.
434447
for (const ResolvedDbgOp &Op : ResolvedDbgOps)
@@ -438,10 +451,6 @@ class TransferTracker {
438451
auto Result = ActiveVLocs.insert(std::make_pair(VarID, NewValue));
439452
if (!Result.second)
440453
Result.first->second = NewValue;
441-
auto &[Var, DILoc] = DVMap.lookupDVID(VarID);
442-
PendingDbgValues.push_back(
443-
std::make_pair(VarID, &*MTracker->emitLoc(ResolvedDbgOps, Var, DILoc,
444-
Value.Properties)));
445454
}
446455

447456
/// Load object with live-in variable values. \p mlocs contains the live-in
@@ -681,6 +690,16 @@ class TransferTracker {
681690

682691
auto &[Var, DILoc] = DVMap.lookupDVID(VarID);
683692

693+
// If the expression is a DW_OP_entry_value, emit the variable location
694+
// as-is.
695+
if (DIExpr->isEntryValue()) {
696+
Register Reg = MTracker->LocIdxToLocID[Num.getLoc()];
697+
MachineOperand MO = MachineOperand::CreateReg(Reg, false);
698+
PendingDbgValues.push_back(std::make_pair(
699+
VarID, &*emitMOLoc(MO, Var, {DIExpr, Prop.Indirect, false})));
700+
return true;
701+
}
702+
684703
// Is the variable appropriate for entry values (i.e., is a parameter).
685704
if (!isEntryValueVariable(Var, DIExpr))
686705
return false;
@@ -707,7 +726,7 @@ class TransferTracker {
707726
DebugVariableID VarID = DVMap.getDVID(Var);
708727

709728
// Ignore non-register locations, we don't transfer those.
710-
if (MI.isUndefDebugValue() ||
729+
if (MI.isUndefDebugValue() || MI.getDebugExpression()->isEntryValue() ||
711730
all_of(MI.debug_operands(),
712731
[](const MachineOperand &MO) { return !MO.isReg(); })) {
713732
auto It = ActiveVLocs.find(VarID);
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# RUN: llc --run-pass=livedebugvalues -o - %s | FileCheck %s --implicit-check-not=DBG_VALUE
2+
# REQUIRES: aarch64-registered-target
3+
4+
# This test covers the scenario where a DBG_VALUE created prior to LiveDebugValues has an entry-value expression.
5+
# It ensures that a clobbered stack copy doesn't crash if used as an entry-value because entry-values can't be clobbered.
6+
7+
--- |
8+
target triple = "aarch64-"
9+
define i32 @baz(i32 swiftasync %arg1, i32 noundef %arg2, i1 %cond) !dbg !4 {
10+
br i1 %cond, label %if.then, label %if.else, !dbg !14
11+
if.then: ; preds = %0
12+
%call = call i32 @foo(i32 noundef %arg1), !dbg !15
13+
br label %if.end, !dbg !18
14+
if.else: ; preds = %0
15+
%call1 = call i32 @foo(i32 noundef %arg2), !dbg !19
16+
br label %if.end
17+
if.end: ; preds = %if.else, %if.then
18+
%temp.0 = phi i32 [ %call, %if.then ], [ %call1, %if.else ], !dbg !21
19+
ret i32 %temp.0, !dbg !22
20+
}
21+
declare i32 @foo(i32)
22+
!llvm.dbg.cu = !{!0}
23+
!llvm.module.flags = !{!2, !3}
24+
!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "ha", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
25+
!1 = !DIFile(filename: "test.c", directory: "hah")
26+
!2 = !{i32 7, !"Dwarf Version", i32 4}
27+
!3 = !{i32 2, !"Debug Info Version", i32 3}
28+
!4 = distinct !DISubprogram(name: "baz", scope: !1, file: !1, line: 3, type: !5, scopeLine: 3, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !8)
29+
!5 = !DISubroutineType(types: !6)
30+
!6 = !{!7, !7, !7, !7}
31+
!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
32+
!8 = !{!9, !10, !11, !12}
33+
!9 = !DILocalVariable(name: "arg1", arg: 1, scope: !4, file: !1, line: 3, type: !7)
34+
!10 = !DILocalVariable(name: "arg2", arg: 2, scope: !4, file: !1, line: 3, type: !7)
35+
!11 = !DILocalVariable(name: "cond", arg: 3, scope: !4, file: !1, line: 3, type: !7)
36+
!12 = !DILocalVariable(name: "local", scope: !4, file: !1, line: 4, type: !7)
37+
!13 = !DILocation(line: 0, scope: !4)
38+
!14 = !DILocation(line: 7, column: 7, scope: !4)
39+
!15 = !DILocation(line: 8, column: 12, scope: !16)
40+
!16 = distinct !DILexicalBlock(scope: !17, file: !1, line: 7, column: 13)
41+
!17 = distinct !DILexicalBlock(scope: !4, file: !1, line: 7, column: 7)
42+
!18 = !DILocation(line: 9, column: 3, scope: !16)
43+
!19 = !DILocation(line: 10, column: 12, scope: !20)
44+
!20 = distinct !DILexicalBlock(scope: !17, file: !1, line: 9, column: 10)
45+
!21 = !DILocation(line: 0, scope: !17)
46+
!22 = !DILocation(line: 13, column: 3, scope: !4)
47+
name: baz
48+
debugInstrRef: true
49+
stack:
50+
- { id: 1, name: '', type: spill-slot, offset: -24, size: 4, alignment: 4,
51+
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
52+
body: |
53+
bb.0 (%ir-block.0):
54+
DBG_VALUE $w1, $noreg, !12, !DIExpression(DW_OP_LLVM_entry_value, 1), debug-location !13
55+
56+
bb.1.if.then:
57+
$w0 = LDRWui $sp, 2
58+
BL @foo, csr_darwin_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit-def $w0, debug-location !15
59+
$w1 = MOVi32imm 0
60+
61+
bb.2.if.else:
62+
$w0 = LDRWui $sp, 3
63+
BL @foo, csr_darwin_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit-def $w0, debug-location !19
64+
STRWui killed $w0, $sp, 1
65+
B %bb.3
66+
67+
bb.3.if.end:
68+
$w0 = LDRWui $sp, 1
69+
$fp, $lr = frame-destroy LDPXi $sp, 2, debug-location !22
70+
$sp = frame-destroy ADDXri $sp, 32, 0, debug-location !22
71+
RET undef $lr, implicit killed $w0, debug-location !22
72+
73+
# CHECK-LABEL: bb.0
74+
# CHECK: DBG_VALUE $w1, {{.*}}, !DIExpression(DW_OP_LLVM_entry_value, 1)
75+
# CHECK-LABEL: bb.1.if.then:
76+
# CHECK: DBG_VALUE $w1, {{.*}}, !DIExpression(DW_OP_LLVM_entry_value, 1)
77+
# CHECK-NEXT: $w0 = LDRWui $sp, 2
78+
# CHECK-NEXT: BL @foo
79+
# CHECK-NEXT: $w1 = MOVi32imm 0
80+
# CHECK-NOT: DBG_VALUE $w1, {{.*}}, !DIExpression(DW_OP_LLVM_entry_value, 1)
81+
# CHECK-LABEL: bb.2.if.else:
82+
# CHECK: DBG_VALUE $w1, {{.*}}, !DIExpression(DW_OP_LLVM_entry_value, 1)
83+
# CHECK-LABEL: bb.3.if.end:
84+
# CHECK: DBG_VALUE $w1, {{.*}}, !DIExpression(DW_OP_LLVM_entry_value, 1)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# RUN: llc --run-pass=livedebugvalues -o - %s | FileCheck %s
2+
# REQUIRES: x86-registered-target
3+
4+
# This test covers the scenario that saves a register on the stack, uses this register as an entry value DBG_VALUE location, and then clobbers it.
5+
6+
--- |
7+
target triple = "x86_64-"
8+
define void @foo(ptr swiftasync %0) !dbg !4 {
9+
call void @llvm.dbg.value(metadata ptr %0, metadata !9, metadata !DIExpression(DW_OP_LLVM_entry_value, 1)), !dbg !17
10+
ret void
11+
}
12+
declare void @llvm.dbg.value(metadata, metadata, metadata)
13+
14+
!llvm.module.flags = !{!0}
15+
!llvm.dbg.cu = !{!1}
16+
17+
!0 = !{i32 2, !"Debug Info Version", i32 3}
18+
!1 = distinct !DICompileUnit(language: DW_LANG_Swift, file: !2, producer: "blah", isOptimized: true, flags: "blah", runtimeVersion: 5, emissionKind: FullDebug)
19+
!2 = !DIFile(filename: "blah", directory: "blah")
20+
!3 = !{}
21+
!4 = distinct !DISubprogram(name: "blah", linkageName: "blah", scope: !2, file: !2, line: 284, type: !7, unit: !1)
22+
!7 = !DISubroutineType(types: !3)
23+
!9 = !DILocalVariable(name: "self", arg: 3, scope: !4, file: !2, line: 328, type: !12, flags: DIFlagArtificial)
24+
!12 = !DICompositeType(tag: DW_TAG_structure_type, name: "blah", scope: !2, file: !2, size: 64, elements: !3)
25+
!17 = !DILocation(line: 328, column: 17, scope: !4)
26+
27+
...
28+
---
29+
name: foo
30+
alignment: 16
31+
debugInstrRef: true
32+
tracksDebugUserValues: true
33+
liveins:
34+
- { reg: '$r14', virtual-reg: '' }
35+
stack:
36+
- { id: 0, name: '', type: spill-slot, offset: -64, size: 8, alignment: 8,
37+
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
38+
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
39+
body: |
40+
bb.0:
41+
liveins: $r14
42+
; Put a copy of r14 on the stack.
43+
MOV64mr $rbp, 1, $noreg, -48, $noreg, $r14 :: (store (s64) into %stack.0)
44+
DBG_VALUE $r14, $noreg, !9, !DIExpression(DW_OP_LLVM_entry_value, 1), debug-location !17
45+
MOV64mi32 $noreg, 1, $noreg, 0, $noreg, 0, debug-location !17 :: (store (s64) into `ptr null`)
46+
$r14 = MOV64rr killed $r13
47+
; Clobber $r14
48+
RETI64 24
49+
# CHECK: bb.0:
50+
# CHECK: MOV64mr $rbp, 1, $noreg, -48, $noreg, $r14
51+
# CHECK-NEXT: DBG_VALUE $r14, {{.*}}, !DIExpression(DW_OP_LLVM_entry_value, 1)
52+
# CHECK-NOT: DBG_VALUE
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# RUN: llc --run-pass=livedebugvalues -o - %s | FileCheck %s --implicit-check-not=DBG_VALUE
2+
# REQUIRES: x86-registered-target
3+
4+
# This test covers the scenario where a DBG_VALUE created prior to LiveDebugValues has an entry-value expression.
5+
# It ensures that a clobbered stack copy doesn't crash if used as an entry-value because entry-values can't be clobbered.
6+
7+
--- |
8+
target triple = "x86_64-"
9+
10+
define i32 @baz(i32 swiftasync %arg1, i32 noundef %arg2, i1 %cond) !dbg !9 {
11+
tail call void @llvm.dbg.value(metadata i32 %arg1, metadata !17, metadata !DIExpression(DW_OP_LLVM_entry_value, 1)), !dbg !19
12+
br i1 %cond, label %if.then, label %if.else, !dbg !22
13+
if.then:
14+
%call = call i32 @foo(i32 noundef %arg1), !dbg !23
15+
br label %if.end, !dbg !25
16+
if.else:
17+
%call1 = call i32 @foo(i32 noundef %arg2), !dbg !26
18+
br label %if.end
19+
if.end:
20+
%temp.0 = phi i32 [ %call, %if.then ], [ %call1, %if.else ], !dbg !28
21+
ret i32 %temp.0, !dbg !29
22+
}
23+
24+
declare i32 @foo(i32)
25+
declare void @llvm.dbg.value(metadata, metadata, metadata)
26+
27+
!llvm.dbg.cu = !{!0}
28+
!llvm.module.flags = !{!2, !3}
29+
30+
!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "ha", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
31+
!1 = !DIFile(filename: "test.c", directory: "hah")
32+
!2 = !{i32 7, !"Dwarf Version", i32 4}
33+
!3 = !{i32 2, !"Debug Info Version", i32 3}
34+
!9 = distinct !DISubprogram(name: "baz", scope: !1, file: !1, line: 3, type: !10, scopeLine: 3, unit: !0, retainedNodes: !13)
35+
!10 = !DISubroutineType(types: !11)
36+
!11 = !{!12, !12, !12, !12}
37+
!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
38+
!13 = !{!14, !15, !16, !17}
39+
!14 = !DILocalVariable(name: "arg1", arg: 1, scope: !9, file: !1, line: 3, type: !12)
40+
!15 = !DILocalVariable(name: "arg2", arg: 2, scope: !9, file: !1, line: 3, type: !12)
41+
!16 = !DILocalVariable(name: "cond", arg: 3, scope: !9, file: !1, line: 3, type: !12)
42+
!17 = !DILocalVariable(name: "local", scope: !9, file: !1, line: 4, type: !12)
43+
!19 = !DILocation(line: 0, scope: !9)
44+
!20 = !DILocation(line: 7, column: 7, scope: !21)
45+
!21 = distinct !DILexicalBlock(scope: !9, file: !1, line: 7, column: 7)
46+
!22 = !DILocation(line: 7, column: 7, scope: !9)
47+
!23 = !DILocation(line: 8, column: 12, scope: !24)
48+
!24 = distinct !DILexicalBlock(scope: !21, file: !1, line: 7, column: 13)
49+
!25 = !DILocation(line: 9, column: 3, scope: !24)
50+
!26 = !DILocation(line: 10, column: 12, scope: !27)
51+
!27 = distinct !DILexicalBlock(scope: !21, file: !1, line: 9, column: 10)
52+
!28 = !DILocation(line: 0, scope: !21)
53+
!29 = !DILocation(line: 13, column: 3, scope: !9)
54+
55+
...
56+
---
57+
name: baz
58+
alignment: 16
59+
debugInstrRef: true
60+
tracksDebugUserValues: true
61+
liveins:
62+
- { reg: '$r14', virtual-reg: '' }
63+
- { reg: '$edi', virtual-reg: '' }
64+
- { reg: '$esi', virtual-reg: '' }
65+
- { reg: '$edx', virtual-reg: '' }
66+
body: |
67+
bb.0:
68+
successors: %bb.2(0x40000000), %bb.1(0x40000000)
69+
liveins: $r14, $edi, $edx, $esi
70+
DBG_VALUE $r14, $noreg, !14, !DIExpression(DW_OP_LLVM_entry_value, 1), debug-location !19
71+
CMP32ri killed renamable $edx, 0, implicit-def $eflags, debug-location !20
72+
JCC_1 %bb.2, 4, implicit killed $eflags, debug-location !22
73+
bb.1.if.then:
74+
successors: %bb.3(0x80000000)
75+
liveins: $edi, $r13
76+
CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $eax, debug-location !23
77+
$r14 = MOV64ri 0, debug-location !20
78+
JMP_1 %bb.3, debug-location !25
79+
bb.2.if.else:
80+
successors: %bb.3(0x80000000)
81+
liveins: $esi, $r13
82+
$edi = MOV32rr killed $esi, debug-location !26
83+
CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $eax, debug-location !26
84+
bb.3.if.end:
85+
liveins: $eax
86+
$rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !29
87+
RET64 implicit $eax, debug-location !29
88+
# CHECK-LABEL: bb.0:
89+
# CHECK: DBG_VALUE $r14, {{.*}}, !DIExpression(DW_OP_LLVM_entry_value, 1)
90+
# CHECK-LABEL: bb.1.if.then:
91+
# CHECK: DBG_VALUE $r14, {{.*}}, !DIExpression(DW_OP_LLVM_entry_value, 1)
92+
# CHECK-NEXT: CALL64pcrel32 @foo
93+
# CHECK-NEXT: $r14 = MOV64ri 0
94+
# CHECK-NOT: DBG_VALUE $r14, {{.*}}, !DIExpression(DW_OP_LLVM_entry_value, 1)
95+
# CHECK-LABEL: bb.2.if.else:
96+
# CHECK: DBG_VALUE $r14, {{.*}}, !DIExpression(DW_OP_LLVM_entry_value, 1)
97+
# CHECK-LABEL: bb.3.if.end:
98+
# CHECK: DBG_VALUE $r14, {{.*}}, !DIExpression(DW_OP_LLVM_entry_value, 1)

0 commit comments

Comments
 (0)