Skip to content

Commit fc5107c

Browse files
committedJun 18, 2019
Add debug location verification for !llvm.loop attachments.
This patch teaches the Verifier how to detect broken !llvm.loop attachments as discussed in https://reviews.llvm.org/D60831. This allows LLVM to warn and strip out the broken debug info before attempting an LTO compilation with input generated by LLVM predating https://reviews.llvm.org/rL361149. rdar://problem/51631158 Differential Revision: https://reviews.llvm.org/D63499 [Re-applies r363725 without changes after fixing a broken testcase.] llvm-svn: 363731
1 parent 1db8d4a commit fc5107c

File tree

2 files changed

+62
-26
lines changed

2 files changed

+62
-26
lines changed
 

‎llvm/lib/IR/Verifier.cpp

+34-26
Original file line numberDiff line numberDiff line change
@@ -2342,36 +2342,44 @@ void Verifier::visitFunction(const Function &F) {
23422342
// FIXME: Check this incrementally while visiting !dbg attachments.
23432343
// FIXME: Only check when N is the canonical subprogram for F.
23442344
SmallPtrSet<const MDNode *, 32> Seen;
2345-
for (auto &BB : F)
2346-
for (auto &I : BB) {
2347-
// Be careful about using DILocation here since we might be dealing with
2348-
// broken code (this is the Verifier after all).
2349-
DILocation *DL =
2350-
dyn_cast_or_null<DILocation>(I.getDebugLoc().getAsMDNode());
2351-
if (!DL)
2352-
continue;
2353-
if (!Seen.insert(DL).second)
2354-
continue;
2345+
auto VisitDebugLoc = [&](const Instruction &I, const MDNode *Node) {
2346+
// Be careful about using DILocation here since we might be dealing with
2347+
// broken code (this is the Verifier after all).
2348+
const DILocation *DL = dyn_cast_or_null<DILocation>(Node);
2349+
if (!DL)
2350+
return;
2351+
if (!Seen.insert(DL).second)
2352+
return;
23552353

2356-
Metadata *Parent = DL->getRawScope();
2357-
AssertDI(Parent && isa<DILocalScope>(Parent),
2358-
"DILocation's scope must be a DILocalScope", N, &F, &I, DL,
2359-
Parent);
2360-
DILocalScope *Scope = DL->getInlinedAtScope();
2361-
if (Scope && !Seen.insert(Scope).second)
2362-
continue;
2354+
Metadata *Parent = DL->getRawScope();
2355+
AssertDI(Parent && isa<DILocalScope>(Parent),
2356+
"DILocation's scope must be a DILocalScope", N, &F, &I, DL,
2357+
Parent);
2358+
DILocalScope *Scope = DL->getInlinedAtScope();
2359+
if (Scope && !Seen.insert(Scope).second)
2360+
return;
23632361

2364-
DISubprogram *SP = Scope ? Scope->getSubprogram() : nullptr;
2362+
DISubprogram *SP = Scope ? Scope->getSubprogram() : nullptr;
23652363

2366-
// Scope and SP could be the same MDNode and we don't want to skip
2367-
// validation in that case
2368-
if (SP && ((Scope != SP) && !Seen.insert(SP).second))
2369-
continue;
2364+
// Scope and SP could be the same MDNode and we don't want to skip
2365+
// validation in that case
2366+
if (SP && ((Scope != SP) && !Seen.insert(SP).second))
2367+
return;
23702368

2371-
// FIXME: Once N is canonical, check "SP == &N".
2372-
AssertDI(SP->describes(&F),
2373-
"!dbg attachment points at wrong subprogram for function", N, &F,
2374-
&I, DL, Scope, SP);
2369+
// FIXME: Once N is canonical, check "SP == &N".
2370+
AssertDI(SP->describes(&F),
2371+
"!dbg attachment points at wrong subprogram for function", N, &F,
2372+
&I, DL, Scope, SP);
2373+
};
2374+
for (auto &BB : F)
2375+
for (auto &I : BB) {
2376+
VisitDebugLoc(I, I.getDebugLoc().getAsMDNode());
2377+
// The llvm.loop annotations also contain two DILocations.
2378+
if (auto MD = I.getMetadata(LLVMContext::MD_loop))
2379+
for (unsigned i = 1; i < MD->getNumOperands(); ++i)
2380+
VisitDebugLoc(I, dyn_cast_or_null<MDNode>(MD->getOperand(i)));
2381+
if (BrokenDebugInfo)
2382+
return;
23752383
}
23762384
}
23772385

‎llvm/test/Verifier/llvm.loop.ll

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
; RUN: llvm-as -disable-output < %s -o /dev/null 2>&1 | FileCheck %s
2+
3+
define i32 @foo() !dbg !4 {
4+
entry:
5+
ret i32 0, !dbg !6
6+
}
7+
8+
define i32 @bar() !dbg !5 {
9+
entry:
10+
; CHECK: !dbg attachment points at wrong subprogram for function
11+
ret i32 0, !dbg !10, !llvm.loop !9
12+
}
13+
14+
; CHECK: warning: ignoring invalid debug info
15+
!llvm.dbg.cu = !{!0}
16+
!llvm.module.flags = !{!7, !8}
17+
18+
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
19+
!1 = !DIFile(filename: "dwarf-test.c", directory: "test")
20+
!2 = !{}
21+
!4 = distinct !DISubprogram(name: "foo", scope: !0, isDefinition: true, unit: !0)
22+
!5 = distinct !DISubprogram(name: "bar", scope: !0, isDefinition: true, unit: !0)
23+
!6 = !DILocation(line: 7, scope: !4)
24+
!7 = !{i32 2, !"Dwarf Version", i32 3}
25+
!8 = !{i32 1, !"Debug Info Version", i32 3}
26+
!9 = !{!9, !10, !11}
27+
!10 = !DILocation(line: 1, scope: !5)
28+
!11 = !DILocation(line: 1, scope: !4)

0 commit comments

Comments
 (0)
Please sign in to comment.