Skip to content

Commit 8525072

Browse files
committed
[DebugInfo][RemoveDIs] Use autoupgrader to convert old debug-info
By chance, two things have prevented the autoupgrade path being exercised much so far: * LLParser setting the debug-info mode to "old" on seeing intrinsics, * The test in AutoUpgrade.cpp wanting to upgrade into a "new" debug-info block. In practice, this appears to mean this code path hasn't seen the various invalid inputs that can come its way. This commit does a number of things: * Tolerates the various illegal inputs that can be written with debug-intrinsics, and that must be tolerated until the Verifier runs, * Printing illegal/null DbgRecord fields must succeed, * Verifier errors need to localise the function/block where the error is, * Tests that now see debug records will print debug-record errors, Plus a few new tests for other intrinsic-to-debug-record failures modes I found. There are also two edge cases: * Some of the unit tests switch back and forth between intrinsic and record modes at will; I've deleted coverage and some assertions to tolerate this as intrinsic support is now Gone (TM), * In sroa-extract-bits.ll, the order of debug records flips. This is because the autoupgrader upgrades in the opposite order to the basic block conversion routines... which doesn't change the record order, but _does_ change the use list order in Metadata! This should (TM) have no consequence to the correctness of LLVM, but will change the order of various records and the order of DWARF record output too. I tried to reduce this patch to a smaller collection of changes, but they're all intertwined, sorry.
1 parent 7433d8c commit 8525072

21 files changed

+313
-102
lines changed

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8336,8 +8336,6 @@ bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS,
83368336
return error(CallLoc, "llvm.dbg intrinsic should not appear in a module "
83378337
"using non-intrinsic debug info");
83388338
}
8339-
if (!SeenOldDbgInfoFormat)
8340-
M->setNewDbgInfoFormatFlag(false);
83418339
SeenOldDbgInfoFormat = true;
83428340
}
83438341
CI->setAttributes(PAL);

llvm/lib/IR/AsmWriter.cpp

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,16 +1204,22 @@ void SlotTracker::processFunctionMetadata(const Function &F) {
12041204
}
12051205

12061206
void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) {
1207+
// Tolerate null metadata pointers: it's a completely illegal debug record,
1208+
// but we can have faulty metadata from debug-intrinsic days being
1209+
// autoupgraded into debug records. This gets caught by the verifier, which
1210+
// then will print the faulty IR, hitting this code path.
12071211
if (const DbgVariableRecord *DVR = dyn_cast<const DbgVariableRecord>(&DR)) {
12081212
// Process metadata used by DbgRecords; we only specifically care about the
12091213
// DILocalVariable, DILocation, and DIAssignID fields, as the Value and
12101214
// Expression fields should only be printed inline and so do not use a slot.
12111215
// Note: The above doesn't apply for empty-metadata operands.
12121216
if (auto *Empty = dyn_cast<MDNode>(DVR->getRawLocation()))
12131217
CreateMetadataSlot(Empty);
1214-
CreateMetadataSlot(DVR->getRawVariable());
1218+
if (DVR->getRawVariable())
1219+
CreateMetadataSlot(DVR->getRawVariable());
12151220
if (DVR->isDbgAssign()) {
1216-
CreateMetadataSlot(cast<MDNode>(DVR->getRawAssignID()));
1221+
if (auto *AssignID = DVR->getRawAssignID())
1222+
CreateMetadataSlot(cast<MDNode>(AssignID));
12171223
if (auto *Empty = dyn_cast<MDNode>(DVR->getRawAddress()))
12181224
CreateMetadataSlot(Empty);
12191225
}
@@ -1222,7 +1228,8 @@ void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) {
12221228
} else {
12231229
llvm_unreachable("unsupported DbgRecord kind");
12241230
}
1225-
CreateMetadataSlot(DR.getDebugLoc().getAsMDNode());
1231+
if (DR.getDebugLoc())
1232+
CreateMetadataSlot(DR.getDebugLoc().getAsMDNode());
12261233
}
12271234

12281235
void SlotTracker::processInstructionMetadata(const Instruction &I) {
@@ -4867,22 +4874,31 @@ void AssemblyWriter::printDbgVariableRecord(const DbgVariableRecord &DVR) {
48674874
llvm_unreachable(
48684875
"Tried to print a DbgVariableRecord with an invalid LocationType!");
48694876
}
4877+
4878+
auto PrintOrNull = [&](Metadata *M) {
4879+
if (!M) {
4880+
Out << "(null)";
4881+
} else {
4882+
WriteAsOperandInternal(Out, M, WriterCtx, true);
4883+
}
4884+
};
4885+
48704886
Out << "(";
4871-
WriteAsOperandInternal(Out, DVR.getRawLocation(), WriterCtx, true);
4887+
PrintOrNull(DVR.getRawLocation());
48724888
Out << ", ";
4873-
WriteAsOperandInternal(Out, DVR.getRawVariable(), WriterCtx, true);
4889+
PrintOrNull(DVR.getRawVariable());
48744890
Out << ", ";
4875-
WriteAsOperandInternal(Out, DVR.getRawExpression(), WriterCtx, true);
4891+
PrintOrNull(DVR.getRawExpression());
48764892
Out << ", ";
48774893
if (DVR.isDbgAssign()) {
4878-
WriteAsOperandInternal(Out, DVR.getRawAssignID(), WriterCtx, true);
4894+
PrintOrNull(DVR.getRawAssignID());
48794895
Out << ", ";
4880-
WriteAsOperandInternal(Out, DVR.getRawAddress(), WriterCtx, true);
4896+
PrintOrNull(DVR.getRawAddress());
48814897
Out << ", ";
4882-
WriteAsOperandInternal(Out, DVR.getRawAddressExpression(), WriterCtx, true);
4898+
PrintOrNull(DVR.getRawAddressExpression());
48834899
Out << ", ";
48844900
}
4885-
WriteAsOperandInternal(Out, DVR.getDebugLoc().getAsMDNode(), WriterCtx, true);
4901+
PrintOrNull(DVR.getDebugLoc().getAsMDNode());
48864902
Out << ")";
48874903
}
48884904

llvm/lib/IR/AutoUpgrade.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,8 +1155,7 @@ static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn,
11551155
case 'd':
11561156
if (Name.consume_front("dbg.")) {
11571157
// Mark debug intrinsics for upgrade to new debug format.
1158-
if (CanUpgradeDebugIntrinsicsToRecords &&
1159-
F->getParent()->IsNewDbgInfoFormat) {
1158+
if (CanUpgradeDebugIntrinsicsToRecords) {
11601159
if (Name == "addr" || Name == "value" || Name == "assign" ||
11611160
Name == "declare" || Name == "label") {
11621161
// There's no function to replace these with.
@@ -4398,11 +4397,25 @@ static Value *upgradeAMDGCNIntrinsicCall(StringRef Name, CallBase *CI,
43984397
/// Helper to unwrap intrinsic call MetadataAsValue operands.
43994398
template <typename MDType>
44004399
static MDType *unwrapMAVOp(CallBase *CI, unsigned Op) {
4401-
if (MetadataAsValue *MAV = dyn_cast<MetadataAsValue>(CI->getArgOperand(Op)))
4402-
return dyn_cast<MDType>(MAV->getMetadata());
4400+
if (Op < CI->arg_size()) {
4401+
if (MetadataAsValue *MAV = dyn_cast<MetadataAsValue>(CI->getArgOperand(Op)))
4402+
// Use a reinterpret cast rather than a safe default-to-null cast: the
4403+
// autoupgrade process happens before the verifier, and thus there might
4404+
// be some nonsense metadata in there.
4405+
return reinterpret_cast<MDType*>(MAV->getMetadata());
4406+
}
44034407
return nullptr;
44044408
}
44054409

4410+
static const DILocation *getDebugLocSafe(const Instruction *I) {
4411+
MDNode *MD = I->getDebugLoc().getAsMDNode();
4412+
// Use a C-style cast here rather than cast<DILocation>. The autoupgrader
4413+
// runs before the verifier, so the Metadata could refer to anything. Allow
4414+
// the verifier to detect and produce an error message, which will be much
4415+
// more ergonomic to the user.
4416+
return (const DILocation*)MD;
4417+
}
4418+
44064419
/// Convert debug intrinsic calls to non-instruction debug records.
44074420
/// \p Name - Final part of the intrinsic name, e.g. 'value' in llvm.dbg.value.
44084421
/// \p CI - The debug intrinsic call.
@@ -4415,19 +4428,19 @@ static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) {
44154428
unwrapMAVOp<Metadata>(CI, 0), unwrapMAVOp<DILocalVariable>(CI, 1),
44164429
unwrapMAVOp<DIExpression>(CI, 2), unwrapMAVOp<DIAssignID>(CI, 3),
44174430
unwrapMAVOp<Metadata>(CI, 4), unwrapMAVOp<DIExpression>(CI, 5),
4418-
CI->getDebugLoc());
4431+
getDebugLocSafe(CI));
44194432
} else if (Name == "declare") {
44204433
DR = new DbgVariableRecord(
44214434
unwrapMAVOp<Metadata>(CI, 0), unwrapMAVOp<DILocalVariable>(CI, 1),
4422-
unwrapMAVOp<DIExpression>(CI, 2), CI->getDebugLoc(),
4435+
unwrapMAVOp<DIExpression>(CI, 2), getDebugLocSafe(CI),
44234436
DbgVariableRecord::LocationType::Declare);
44244437
} else if (Name == "addr") {
44254438
// Upgrade dbg.addr to dbg.value with DW_OP_deref.
44264439
DIExpression *Expr = unwrapMAVOp<DIExpression>(CI, 2);
44274440
Expr = DIExpression::append(Expr, dwarf::DW_OP_deref);
44284441
DR = new DbgVariableRecord(unwrapMAVOp<Metadata>(CI, 0),
44294442
unwrapMAVOp<DILocalVariable>(CI, 1), Expr,
4430-
CI->getDebugLoc());
4443+
getDebugLocSafe(CI));
44314444
} else if (Name == "value") {
44324445
// An old version of dbg.value had an extra offset argument.
44334446
unsigned VarOp = 1;
@@ -4442,7 +4455,7 @@ static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) {
44424455
}
44434456
DR = new DbgVariableRecord(
44444457
unwrapMAVOp<Metadata>(CI, 0), unwrapMAVOp<DILocalVariable>(CI, VarOp),
4445-
unwrapMAVOp<DIExpression>(CI, ExprOp), CI->getDebugLoc());
4458+
unwrapMAVOp<DIExpression>(CI, ExprOp), getDebugLocSafe(CI));
44464459
}
44474460
assert(DR && "Unhandled intrinsic kind in upgrade to DbgRecord");
44484461
CI->getParent()->insertDbgRecordBefore(DR, CI->getIterator());

llvm/lib/IR/BasicBlock.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ using namespace llvm;
3232
STATISTIC(NumInstrRenumberings, "Number of renumberings across all blocks");
3333

3434
DbgMarker *BasicBlock::createMarker(Instruction *I) {
35-
assert(IsNewDbgInfoFormat &&
36-
"Tried to create a marker in a non new debug-info block!");
3735
if (I->DebugMarker)
3836
return I->DebugMarker;
3937
DbgMarker *Marker = new DbgMarker();
@@ -43,8 +41,6 @@ DbgMarker *BasicBlock::createMarker(Instruction *I) {
4341
}
4442

4543
DbgMarker *BasicBlock::createMarker(InstListType::iterator It) {
46-
assert(IsNewDbgInfoFormat &&
47-
"Tried to create a marker in a non new debug-info block!");
4844
if (It != end())
4945
return createMarker(&*It);
5046
DbgMarker *DM = getTrailingDbgRecords();

llvm/lib/IR/Verifier.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6710,38 +6710,38 @@ void Verifier::visit(DbgVariableRecord &DVR) {
67106710
CheckDI(DVR.getType() == DbgVariableRecord::LocationType::Value ||
67116711
DVR.getType() == DbgVariableRecord::LocationType::Declare ||
67126712
DVR.getType() == DbgVariableRecord::LocationType::Assign,
6713-
"invalid #dbg record type", &DVR, DVR.getType());
6713+
"invalid #dbg record type", &DVR, DVR.getType(), BB, F);
67146714

67156715
// The location for a DbgVariableRecord must be either a ValueAsMetadata,
67166716
// DIArgList, or an empty MDNode (which is a legacy representation for an
67176717
// "undef" location).
67186718
auto *MD = DVR.getRawLocation();
67196719
CheckDI(MD && (isa<ValueAsMetadata>(MD) || isa<DIArgList>(MD) ||
67206720
(isa<MDNode>(MD) && !cast<MDNode>(MD)->getNumOperands())),
6721-
"invalid #dbg record address/value", &DVR, MD);
6721+
"invalid #dbg record address/value", &DVR, MD, BB, F);
67226722
if (auto *VAM = dyn_cast<ValueAsMetadata>(MD)) {
67236723
visitValueAsMetadata(*VAM, F);
67246724
if (DVR.isDbgDeclare()) {
67256725
// Allow integers here to support inttoptr salvage.
67266726
Type *Ty = VAM->getValue()->getType();
67276727
CheckDI(Ty->isPointerTy() || Ty->isIntegerTy(),
6728-
"location of #dbg_declare must be a pointer or int", &DVR, MD);
6728+
"location of #dbg_declare must be a pointer or int", &DVR, MD, BB, F);
67296729
}
67306730
} else if (auto *AL = dyn_cast<DIArgList>(MD)) {
67316731
visitDIArgList(*AL, F);
67326732
}
67336733

67346734
CheckDI(isa_and_nonnull<DILocalVariable>(DVR.getRawVariable()),
6735-
"invalid #dbg record variable", &DVR, DVR.getRawVariable());
6735+
"invalid #dbg record variable", &DVR, DVR.getRawVariable(), BB, F);
67366736
visitMDNode(*DVR.getRawVariable(), AreDebugLocsAllowed::No);
67376737

67386738
CheckDI(isa_and_nonnull<DIExpression>(DVR.getRawExpression()),
6739-
"invalid #dbg record expression", &DVR, DVR.getRawExpression());
6739+
"invalid #dbg record expression", &DVR, DVR.getRawExpression(), BB, F);
67406740
visitMDNode(*DVR.getExpression(), AreDebugLocsAllowed::No);
67416741

67426742
if (DVR.isDbgAssign()) {
67436743
CheckDI(isa_and_nonnull<DIAssignID>(DVR.getRawAssignID()),
6744-
"invalid #dbg_assign DIAssignID", &DVR, DVR.getRawAssignID());
6744+
"invalid #dbg_assign DIAssignID", &DVR, DVR.getRawAssignID(), BB, F);
67456745
visitMDNode(*cast<DIAssignID>(DVR.getRawAssignID()),
67466746
AreDebugLocsAllowed::No);
67476747

@@ -6752,29 +6752,29 @@ void Verifier::visit(DbgVariableRecord &DVR) {
67526752
CheckDI(
67536753
isa<ValueAsMetadata>(RawAddr) ||
67546754
(isa<MDNode>(RawAddr) && !cast<MDNode>(RawAddr)->getNumOperands()),
6755-
"invalid #dbg_assign address", &DVR, DVR.getRawAddress());
6755+
"invalid #dbg_assign address", &DVR, DVR.getRawAddress(), BB, F);
67566756
if (auto *VAM = dyn_cast<ValueAsMetadata>(RawAddr))
67576757
visitValueAsMetadata(*VAM, F);
67586758

67596759
CheckDI(isa_and_nonnull<DIExpression>(DVR.getRawAddressExpression()),
67606760
"invalid #dbg_assign address expression", &DVR,
6761-
DVR.getRawAddressExpression());
6761+
DVR.getRawAddressExpression(), BB, F);
67626762
visitMDNode(*DVR.getAddressExpression(), AreDebugLocsAllowed::No);
67636763

67646764
// All of the linked instructions should be in the same function as DVR.
67656765
for (Instruction *I : at::getAssignmentInsts(&DVR))
67666766
CheckDI(DVR.getFunction() == I->getFunction(),
6767-
"inst not in same function as #dbg_assign", I, &DVR);
6767+
"inst not in same function as #dbg_assign", I, &DVR, BB, F);
67686768
}
67696769

67706770
// This check is redundant with one in visitLocalVariable().
67716771
DILocalVariable *Var = DVR.getVariable();
67726772
CheckDI(isType(Var->getRawType()), "invalid type ref", Var,
6773-
Var->getRawType());
6773+
Var->getRawType(), BB, F);
67746774

67756775
auto *DLNode = DVR.getDebugLoc().getAsMDNode();
67766776
CheckDI(isa_and_nonnull<DILocation>(DLNode), "invalid #dbg record DILocation",
6777-
&DVR, DLNode);
6777+
&DVR, DLNode, BB, F);
67786778
DILocation *Loc = DVR.getDebugLoc();
67796779

67806780
// The scopes for variables and !dbg attachments must agree.
@@ -6786,7 +6786,7 @@ void Verifier::visit(DbgVariableRecord &DVR) {
67866786
CheckDI(VarSP == LocSP,
67876787
"mismatched subprogram between #dbg record variable and DILocation",
67886788
&DVR, BB, F, Var, Var->getScope()->getSubprogram(), Loc,
6789-
Loc->getScope()->getSubprogram());
6789+
Loc->getScope()->getSubprogram(), BB, F);
67906790

67916791
verifyFnArgs(DVR);
67926792
}

llvm/test/Assembler/drop-debug-info-nonzero-alloca.ll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@ entry:
1212
metadata ptr undef,
1313
metadata !DILocalVariable(scope: !1),
1414
metadata !DIExpression())
15-
; AS: llvm.dbg.value intrinsic requires a !dbg attachment
15+
; AS: invalid #dbg record DILocation
16+
; AS: #dbg_value(ptr undef, !{{[0-9]+}}, !DIExpression(), (null))
17+
; AS: label %entry
18+
; AS: ptr @foo
1619
; AS: warning: ignoring invalid debug info in <stdin>
20+
1721
ret void
1822
}
1923

llvm/test/DebugInfo/Generic/assignment-tracking/parse-and-verify/verify.ll

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
define dso_local void @fun2() !dbg !15 {
1010
;; DIAssignID copied here from @fun() where it is used by intrinsics.
11-
; CHECK: dbg.assign not in same function as inst
11+
; CHECK: DVRAssign not in same function as inst
1212
%x = alloca i32, align 4, !DIAssignID !14
1313
ret void
1414
}
@@ -17,24 +17,24 @@ define dso_local void @fun() !dbg !7 {
1717
entry:
1818
%a = alloca i32, align 4, !DIAssignID !14
1919
;; Here something other than a dbg.assign intrinsic is using a DIAssignID.
20-
; CHECK: !DIAssignID should only be used by llvm.dbg.assign intrinsics
20+
; CHECK: !DIAssignID should only be used by Assign DVRs
2121
call void @llvm.dbg.value(metadata !14, metadata !10, metadata !DIExpression()), !dbg !13
2222

2323
;; Each following dbg.assign has an argument of the incorrect type.
24-
; CHECK: invalid llvm.dbg.assign intrinsic address/value
24+
; CHECK: invalid #dbg record address/value
2525
call void @llvm.dbg.assign(metadata !3, metadata !10, metadata !DIExpression(), metadata !14, metadata ptr undef, metadata !DIExpression()), !dbg !13
26-
; CHECK: invalid llvm.dbg.assign intrinsic variable
26+
; CHECK: invalid #dbg record variable
2727
call void @llvm.dbg.assign(metadata i32 0, metadata !2, metadata !DIExpression(), metadata !14, metadata ptr undef, metadata !DIExpression()), !dbg !13
28-
; CHECK: invalid llvm.dbg.assign intrinsic expression
28+
; CHECK: invalid #dbg record expression
2929
call void @llvm.dbg.assign(metadata !14, metadata !10, metadata !2, metadata !14, metadata ptr undef, metadata !DIExpression()), !dbg !13
30-
; CHECK: invalid llvm.dbg.assign intrinsic DIAssignID
30+
; CHECK: invalid #dbg_assign DIAssignID
3131
call void @llvm.dbg.assign(metadata !14, metadata !10, metadata !DIExpression(), metadata !2, metadata ptr undef, metadata !DIExpression()), !dbg !13
32-
; CHECK: invalid llvm.dbg.assign intrinsic address
32+
; CHECK: invalid #dbg_assign address
3333
call void @llvm.dbg.assign(metadata !14, metadata !10, metadata !DIExpression(), metadata !14, metadata !3, metadata !DIExpression()), !dbg !13
3434
;; Empty metadata debug operands are allowed.
35-
; CHECK-NOT: invalid llvm.dbg.assign
35+
; CHECK-NOT: invalid #dbg record
3636
call void @llvm.dbg.assign(metadata !14, metadata !10, metadata !DIExpression(), metadata !14, metadata !2, metadata !DIExpression()), !dbg !13
37-
; CHECK: invalid llvm.dbg.assign intrinsic address expression
37+
; CHECK: invalid #dbg_assign address expression
3838
call void @llvm.dbg.assign(metadata !14, metadata !10, metadata !DIExpression(), metadata !14, metadata ptr undef, metadata !2), !dbg !13
3939
ret void
4040
}

0 commit comments

Comments
 (0)