Skip to content

Commit be5734d

Browse files
committed
[DebugInfo][InstrRef] Don't fire assertions if debug-info is faulty
It's inevitable that optimisation passes will fail to update debug-info: when that happens, it's best if the compiler doesn't crash as a result. Therefore, downgrade a few assertions / failure modes that would crash when illegal debug-info was seen, to instead drop variable locations. In practice this means that an instruction reference to a nonexistant or illegal operand should be tolerated. Differential Revision: https://reviews.llvm.org/D118998
1 parent 8fa45b8 commit be5734d

File tree

3 files changed

+187
-25
lines changed

3 files changed

+187
-25
lines changed

llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,15 +1091,25 @@ bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI,
10911091
if (L)
10921092
NewID = ValueIDNum(BlockNo, InstrIt->second.second, *L);
10931093
} else if (OpNo != MachineFunction::DebugOperandMemNumber) {
1094-
assert(OpNo < TargetInstr.getNumOperands());
1095-
const MachineOperand &MO = TargetInstr.getOperand(OpNo);
1096-
1097-
// Today, this can only be a register.
1098-
assert(MO.isReg() && MO.isDef());
1094+
// Permit the debug-info to be completely wrong: identifying a nonexistant
1095+
// operand, or one that is not a register definition, means something
1096+
// unexpected happened during optimisation. Broken debug-info, however,
1097+
// shouldn't crash the compiler -- instead leave the variable value as
1098+
// None, which will make it appear "optimised out".
1099+
if (OpNo < TargetInstr.getNumOperands()) {
1100+
const MachineOperand &MO = TargetInstr.getOperand(OpNo);
1101+
1102+
if (MO.isReg() && MO.isDef() && MO.getReg()) {
1103+
unsigned LocID = MTracker->getLocID(MO.getReg());
1104+
LocIdx L = MTracker->LocIDToLocIdx[LocID];
1105+
NewID = ValueIDNum(BlockNo, InstrIt->second.second, L);
1106+
}
1107+
}
10991108

1100-
unsigned LocID = MTracker->getLocID(MO.getReg());
1101-
LocIdx L = MTracker->LocIDToLocIdx[LocID];
1102-
NewID = ValueIDNum(BlockNo, InstrIt->second.second, L);
1109+
if (!NewID) {
1110+
LLVM_DEBUG(
1111+
{ dbgs() << "Seen instruction reference to illegal operand\n"; });
1112+
}
11031113
}
11041114
// else: NewID is left as None.
11051115
} else if (PHIIt != DebugPHINumToValue.end() && PHIIt->InstrNum == InstNo) {
@@ -1249,7 +1259,16 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) {
12491259
const MachineOperand &MO = MI.getOperand(0);
12501260
unsigned InstrNum = MI.getOperand(1).getImm();
12511261

1252-
if (MO.isReg()) {
1262+
auto EmitBadPHI = [this, &MI, InstrNum](void) -> bool {
1263+
// Helper lambda to do any accounting when we fail to find a location for
1264+
// a DBG_PHI. This can happen if DBG_PHIs are malformed, or refer to a
1265+
// dead stack slot, for example.
1266+
// Record a DebugPHIRecord with an empty value + location.
1267+
DebugPHINumToValue.push_back({InstrNum, MI.getParent(), None, None});
1268+
return true;
1269+
};
1270+
1271+
if (MO.isReg() && MO.getReg()) {
12531272
// The value is whatever's currently in the register. Read and record it,
12541273
// to be analysed later.
12551274
Register Reg = MO.getReg();
@@ -1261,15 +1280,14 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) {
12611280
// Ensure this register is tracked.
12621281
for (MCRegAliasIterator RAI(MO.getReg(), TRI, true); RAI.isValid(); ++RAI)
12631282
MTracker->lookupOrTrackRegister(*RAI);
1264-
} else {
1283+
} else if (MO.isFI()) {
12651284
// The value is whatever's in this stack slot.
1266-
assert(MO.isFI());
12671285
unsigned FI = MO.getIndex();
12681286

12691287
// If the stack slot is dead, then this was optimized away.
12701288
// FIXME: stack slot colouring should account for slots that get merged.
12711289
if (MFI->isDeadObjectIndex(FI))
1272-
return true;
1290+
return EmitBadPHI();
12731291

12741292
// Identify this spill slot, ensure it's tracked.
12751293
Register Base;
@@ -1280,7 +1298,7 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) {
12801298
// We might be able to find a value, but have chosen not to, to avoid
12811299
// tracking too much stack information.
12821300
if (!SpillNo)
1283-
return true;
1301+
return EmitBadPHI();
12841302

12851303
// Problem: what value should we extract from the stack? LLVM does not
12861304
// record what size the last store to the slot was, and it would become
@@ -1315,8 +1333,17 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) {
13151333
}
13161334

13171335
// Record this DBG_PHI for later analysis.
1318-
auto DbgPHI = DebugPHIRecord({InstrNum, MI.getParent(), *Result, *SpillLoc});
1336+
auto DbgPHI =
1337+
DebugPHIRecord({InstrNum, MI.getParent(), *Result, *SpillLoc});
13191338
DebugPHINumToValue.push_back(DbgPHI);
1339+
} else {
1340+
// Else: if the operand is neither a legal register or a stack slot, then
1341+
// we're being fed illegal debug-info. Record an empty PHI, so that any
1342+
// debug users trying to read this number will be put off trying to
1343+
// interpret the value.
1344+
LLVM_DEBUG(
1345+
{ dbgs() << "Seen DBG_PHI with unrecognised operand format\n"; });
1346+
return EmitBadPHI();
13201347
}
13211348

13221349
return true;
@@ -3165,7 +3192,10 @@ bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF,
31653192
// either live-through machine values, or PHIs.
31663193
for (auto &DBG_PHI : DebugPHINumToValue) {
31673194
// Identify unresolved block-live-ins.
3168-
ValueIDNum &Num = DBG_PHI.ValueRead;
3195+
if (!DBG_PHI.ValueRead)
3196+
continue;
3197+
3198+
ValueIDNum &Num = *DBG_PHI.ValueRead;
31693199
if (!Num.isPHI())
31703200
continue;
31713201

@@ -3566,17 +3596,24 @@ Optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl(
35663596
if (LowerIt == UpperIt)
35673597
return None;
35683598

3599+
// If any DBG_PHIs referred to a location we didn't understand, don't try to
3600+
// compute a value. There might be scenarios where we could recover a value
3601+
// for some range of DBG_INSTR_REFs, but at this point we can have high
3602+
// confidence that we've seen a bug.
3603+
auto DBGPHIRange = make_range(LowerIt, UpperIt);
3604+
for (const DebugPHIRecord &DBG_PHI : DBGPHIRange)
3605+
if (!DBG_PHI.ValueRead)
3606+
return None;
3607+
35693608
// If there's only one DBG_PHI, then that is our value number.
35703609
if (std::distance(LowerIt, UpperIt) == 1)
3571-
return LowerIt->ValueRead;
3572-
3573-
auto DBGPHIRange = make_range(LowerIt, UpperIt);
3610+
return *LowerIt->ValueRead;
35743611

35753612
// Pick out the location (physreg, slot) where any PHIs must occur. It's
35763613
// technically possible for us to merge values in different registers in each
35773614
// block, but highly unlikely that LLVM will generate such code after register
35783615
// allocation.
3579-
LocIdx Loc = LowerIt->ReadLoc;
3616+
LocIdx Loc = *LowerIt->ReadLoc;
35803617

35813618
// We have several DBG_PHIs, and a use position (the Here inst). All each
35823619
// DBG_PHI does is identify a value at a program position. We can treat each
@@ -3595,7 +3632,7 @@ Optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl(
35953632
// for the SSAUpdater.
35963633
for (const auto &DBG_PHI : DBGPHIRange) {
35973634
LDVSSABlock *Block = Updater.getSSALDVBlock(DBG_PHI.MBB);
3598-
const ValueIDNum &Num = DBG_PHI.ValueRead;
3635+
const ValueIDNum &Num = *DBG_PHI.ValueRead;
35993636
AvailableValues.insert(std::make_pair(Block, Num.asU64()));
36003637
}
36013638

@@ -3629,7 +3666,7 @@ Optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl(
36293666
// Define all the input DBG_PHI values in ValidatedValues.
36303667
for (const auto &DBG_PHI : DBGPHIRange) {
36313668
LDVSSABlock *Block = Updater.getSSALDVBlock(DBG_PHI.MBB);
3632-
const ValueIDNum &Num = DBG_PHI.ValueRead;
3669+
const ValueIDNum &Num = *DBG_PHI.ValueRead;
36333670
ValidatedValues.insert(std::make_pair(Block, Num));
36343671
}
36353672

llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -851,10 +851,16 @@ class InstrRefBasedLDV : public LDVImpl {
851851
/// Record of where we observed a DBG_PHI instruction.
852852
class DebugPHIRecord {
853853
public:
854-
uint64_t InstrNum; ///< Instruction number of this DBG_PHI.
855-
MachineBasicBlock *MBB; ///< Block where DBG_PHI occurred.
856-
ValueIDNum ValueRead; ///< The value number read by the DBG_PHI.
857-
LocIdx ReadLoc; ///< Register/Stack location the DBG_PHI reads.
854+
/// Instruction number of this DBG_PHI.
855+
uint64_t InstrNum;
856+
/// Block where DBG_PHI occurred.
857+
MachineBasicBlock *MBB;
858+
/// The value number read by the DBG_PHI -- or None if it didn't refer to
859+
/// a value.
860+
Optional<ValueIDNum> ValueRead;
861+
/// Register/Stack location the DBG_PHI reads -- or None if it referred to
862+
/// something unexpected.
863+
Optional<LocIdx> ReadLoc;
858864

859865
operator unsigned() const { return InstrNum; }
860866
};
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
--- |
2+
; RUN: llc %s -march=x86-64 -run-pass=livedebugvalues -o - -experimental-debug-variable-locations | FileCheck %s -implicit-check-not=DBG_VALUE
3+
;
4+
; Test that InstrRefBasedLDV / livedebugvalues doesn't crash when it sees
5+
; illegal instruction referencing debug-info. This can be caused by
6+
; optimisations not updating debug-info or doing it incorrectly, which is
7+
; inevitable. When that happens, we should safely drop the variable location,
8+
; but not crash.
9+
10+
define i32 @_Z8bb_to_bb() local_unnamed_addr !dbg !12 {
11+
entry:
12+
ret i32 0, !dbg !17
13+
}
14+
15+
!llvm.dbg.cu = !{!0}
16+
!llvm.module.flags = !{!7, !8, !9, !10}
17+
!llvm.ident = !{!11}
18+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 10.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3, debugInfoForProfiling: true, nameTableKind: None)
19+
!1 = !DIFile(filename: "main.cpp", directory: "F:\")
20+
!2 = !{}
21+
!3 = !{!4}
22+
!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression())
23+
!5 = distinct !DIGlobalVariable(name: "start", scope: !0, file: !1, line: 4, type: !6, isLocal: false, isDefinition: true)
24+
!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
25+
!7 = !{i32 2, !"Dwarf Version", i32 4}
26+
!8 = !{i32 2, !"Debug Info Version", i32 3}
27+
!9 = !{i32 1, !"wchar_size", i32 2}
28+
!10 = !{i32 7, !"PIC Level", i32 2}
29+
!11 = !{!"clang version 10.0.0"}
30+
!12 = distinct !DISubprogram(name: "bb_to_bb", linkageName: "bb_to_bb", scope: !1, file: !1, line: 6, type: !13, scopeLine: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !15)
31+
!13 = !DISubroutineType(types: !14)
32+
!14 = !{!6, !6}
33+
!15 = !{!16}
34+
!16 = !DILocalVariable(name: "myVar", scope: !12, file: !1, line: 7, type: !6)
35+
!17 = !DILocation(line: 10, scope: !12)
36+
37+
...
38+
---
39+
name: _Z8bb_to_bb
40+
debugValueSubstitutions:
41+
- { srcinst: 4, srcop: 0, dstinst: 3, dstop: 0, subreg: 0 }
42+
body: |
43+
bb.0.entry:
44+
successors: %bb.1, %bb.2
45+
; CHECK-LABE: bb.0.entry:
46+
47+
$rax = MOV64ri 1, debug-instr-number 1, debug-location !17
48+
DBG_INSTR_REF 1, 0, !16, !DIExpression(), debug-location !17
49+
;; First check that picking out location works as usual.
50+
; CHECK: DBG_INSTR_REF 1, 0
51+
; CHECK-NEXT: DBG_VALUE $rax
52+
53+
$rax = MOV64ri 1, debug-instr-number 2, debug-location !17
54+
DBG_INSTR_REF 2, 999, !16, !DIExpression(), debug-location !17
55+
;; Test out of bounds operand number.
56+
; CHECK: DBG_INSTR_REF 2, 999
57+
; CHECK-NEXT: DBG_VALUE $noreg
58+
59+
$rax = MOV64ri 1, debug-instr-number 3, debug-location !17
60+
DBG_INSTR_REF 3, 1, !16, !DIExpression(), debug-location !17
61+
;; Test non-register operand
62+
; CHECK: DBG_INSTR_REF 3, 1
63+
; CHECK-NEXT: DBG_VALUE $noreg
64+
65+
;; FIXME: We should test what happens when this meta-instruction is seen
66+
;; by livedbugvalues with an instruction number. However, right now it's
67+
;; impossible to turn the machine-code verifier off when loading MIR?
68+
;KILL implicit killed $eflags, debug-instr-number 4, debug-location !17
69+
;DBG_INSTR_REF 4, 0, !16, !DIExpression(), debug-location !17
70+
;;; Test non-def operand
71+
;; check: DBG_INSTR_REF 4, 0
72+
;; check-next: DBG_VALUE $noreg
73+
74+
$noreg = MOV32ri 1, debug-instr-number 5, debug-location !17
75+
DBG_INSTR_REF 5, 0, !16, !DIExpression(), debug-location !17
76+
;; Def of $noreg?
77+
; CHECK: DBG_INSTR_REF 5, 0
78+
; CHECK-NEXT: DBG_VALUE $noreg
79+
80+
JCC_1 %bb.1, 1, implicit $eflags
81+
JMP_1 %bb.2
82+
83+
bb.1:
84+
successors: %bb.3
85+
; CHECK-LABEL: bb.1:
86+
87+
DBG_PHI $rax, 6
88+
DBG_INSTR_REF 6, 1, !16, !DIExpression(), debug-location !17
89+
;; Test out-of-bounds reference to a DBG_PHI.
90+
; CHECK: DBG_INSTR_REF 6, 1
91+
; CHECK-NEXT: DBG_VALUE $noreg
92+
93+
DBG_PHI $noreg, 7
94+
JMP_1 %bb.3
95+
96+
bb.2:
97+
successors: %bb.3
98+
; CHECK-LABEL: bb.2:
99+
DBG_PHI 1, 6
100+
DBG_INSTR_REF 6, 0, !16, !DIExpression(), debug-location !17
101+
;; Test non-reg operand to DBG_PHI. It's not clear if this can ever happen
102+
;; as the result of an optimisation, but lets test for it anyway.
103+
; CHECK: DBG_INSTR_REF 6, 0
104+
; CHECK-NEXT: DBG_VALUE $noreg
105+
106+
DBG_PHI 1, 7
107+
JMP_1 %bb.3
108+
109+
bb.3:
110+
; CHECK-LABEL: bb.3:
111+
DBG_INSTR_REF 7, 0, !16, !DIExpression(), debug-location !17
112+
;; PHI resolution of illegal inputs shouldn't crash either. It should also
113+
;; come out as a $noreg location.
114+
; CHECK: DBG_INSTR_REF 7, 0
115+
; CHECK-NEXT: DBG_VALUE $noreg
116+
117+
RET 0, debug-location !17
118+
119+
...

0 commit comments

Comments
 (0)