From 08e687e68451ce435724e7e85c52303090da0b1b Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Sun, 15 Mar 2015 01:21:30 +0000 Subject: [PATCH] Verifier: Check debug info intrinsic arguments Verify that debug info intrinsic arguments are valid. (These checks will not recurse through the full debug info graph, so they don't need to be cordoned of in `DebugInfoVerifier`.) With those checks in place, changing the `DbgIntrinsicInst` accessors to downcast to `MDLocalVariable` and `MDExpression` is natural (added isa specializations in `Metadata.h` to support this). Added tests to `test/Verifier` for the new -verify checks, and fixed the debug info in all the in-tree tests. If you have out-of-tree testcases that have started to fail to -verify, hopefully the verify checks are helpful. The most likely problem is that the expression argument is `!{}` (instead of `!MDExpression()`). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@232296 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/IntrinsicInst.h | 26 ++++++++++--------- lib/IR/Verifier.cpp | 24 +++++++++++++++++ test/DebugInfo/2010-03-19-DbgDeclare.ll | 2 +- .../AddDiscriminators/no-discriminators.ll | 2 +- .../DeadArgElim/2010-04-30-DbgInfo.ll | 18 ++++++------- .../DeadStoreElimination/inst-limits.ll | 4 +-- test/Transforms/GCOVProfiling/linezero.ll | 8 +++--- test/Transforms/Inline/ignore-debug-info.ll | 12 ++++----- test/Transforms/InstCombine/debuginfo.ll | 6 ++--- test/Transforms/LICM/debug-value.ll | 2 +- test/Transforms/LoopIdiom/debug-line.ll | 6 ++--- test/Transforms/LoopRotate/dbgvalue.ll | 8 +++--- test/Transforms/LoopVectorize/dbg.value.ll | 4 +-- test/Transforms/LoopVectorize/debugloc.ll | 12 ++++----- test/Transforms/Mem2Reg/ConvertDebugInfo.ll | 4 +-- test/Transforms/Mem2Reg/ConvertDebugInfo2.ll | 8 +++--- test/Transforms/ObjCARC/basic.ll | 4 +-- ...e-that-exception-unwind-path-is-visited.ll | 8 +++--- .../SLPVectorizer/X86/debug_info.ll | 10 +++---- test/Transforms/SampleProfile/branch.ll | 12 ++++----- .../ScalarRepl/debuginfo-preserved.ll | 6 ++--- test/Transforms/Scalarizer/dbginfo.ll | 6 ++--- test/Transforms/SimplifyCFG/hoist-dbgvalue.ll | 8 +++--- .../StripSymbols/strip-dead-debug-info.ll | 2 +- test/Verifier/llvm.dbg.declare-address.ll | 16 ++++++++++++ test/Verifier/llvm.dbg.declare-expression.ll | 16 ++++++++++++ test/Verifier/llvm.dbg.declare-variable.ll | 16 ++++++++++++ test/Verifier/llvm.dbg.value-expression.ll | 16 ++++++++++++ test/Verifier/llvm.dbg.value-value.ll | 16 ++++++++++++ test/Verifier/llvm.dbg.value-variable.ll | 16 ++++++++++++ 30 files changed, 210 insertions(+), 88 deletions(-) create mode 100644 test/Verifier/llvm.dbg.declare-address.ll create mode 100644 test/Verifier/llvm.dbg.declare-expression.ll create mode 100644 test/Verifier/llvm.dbg.declare-variable.ll create mode 100644 test/Verifier/llvm.dbg.value-expression.ll create mode 100644 test/Verifier/llvm.dbg.value-value.ll create mode 100644 test/Verifier/llvm.dbg.value-variable.ll diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h index d4344322ce3..72ab46d8af9 100644 --- a/include/llvm/IR/IntrinsicInst.h +++ b/include/llvm/IR/IntrinsicInst.h @@ -82,13 +82,14 @@ namespace llvm { class DbgDeclareInst : public DbgInfoIntrinsic { public: Value *getAddress() const; - MDNode *getVariable() const { - return cast( - cast(getArgOperand(1))->getMetadata()); + MDNode *getVariable() const { return cast(getRawVariable()); } + MDNode *getExpression() const { return cast(getRawExpression()); } + + Metadata *getRawVariable() const { + return cast(getArgOperand(1))->getMetadata(); } - MDNode *getExpression() const { - return cast( - cast(getArgOperand(2))->getMetadata()); + Metadata *getRawExpression() const { + return cast(getArgOperand(2))->getMetadata(); } // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -110,13 +111,14 @@ namespace llvm { return cast( const_cast(getArgOperand(1)))->getZExtValue(); } - MDNode *getVariable() const { - return cast( - cast(getArgOperand(2))->getMetadata()); + MDNode *getVariable() const { return cast(getRawVariable()); } + MDNode *getExpression() const { return cast(getRawExpression()); } + + Metadata *getRawVariable() const { + return cast(getArgOperand(2))->getMetadata(); } - MDNode *getExpression() const { - return cast( - cast(getArgOperand(3))->getMetadata()); + Metadata *getRawExpression() const { + return cast(getArgOperand(3))->getMetadata(); } // Methods for support type inquiry through isa, cast, and dyn_cast: diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 1e1355000e8..f0071060276 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -329,6 +329,8 @@ private: void visitUserOp1(Instruction &I); void visitUserOp2(Instruction &I) { visitUserOp1(I); } void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI); + template + void visitDbgIntrinsic(StringRef Kind, DbgIntrinsicTy &DII); void visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI); void visitAtomicRMWInst(AtomicRMWInst &RMWI); void visitFenceInst(FenceInst &FI); @@ -2798,6 +2800,10 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { case Intrinsic::dbg_declare: // llvm.dbg.declare Assert(isa(CI.getArgOperand(0)), "invalid llvm.dbg.declare intrinsic call 1", &CI); + visitDbgIntrinsic("declare", cast(CI)); + break; + case Intrinsic::dbg_value: // llvm.dbg.value + visitDbgIntrinsic("value", cast(CI)); break; case Intrinsic::memcpy: case Intrinsic::memmove: @@ -3012,6 +3018,24 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { }; } +template +void Verifier::visitDbgIntrinsic(StringRef Kind, DbgIntrinsicTy &DII) { + auto *MD = cast(DII.getArgOperand(0))->getMetadata(); + Assert(isa(MD) || + (isa(MD) && !cast(MD)->getNumOperands()), + "invalid llvm.dbg." + Kind + " intrinsic address/value", &DII, MD); + Assert(isa(DII.getRawVariable()), + "invalid llvm.dbg." + Kind + " intrinsic variable", &DII, + DII.getRawVariable()); + Assert(isa(DII.getRawExpression()), + "invalid llvm.dbg." + Kind + " intrinsic expression", &DII, + DII.getRawExpression()); + + // Don't call visitMDNode(), since that will recurse through operands. + visitMDLocalVariable(*cast(DII.getVariable())); + visitMDExpression(*cast(DII.getExpression())); +} + void DebugInfoVerifier::verifyDebugInfo() { if (!VerifyDebugInfo) return; diff --git a/test/DebugInfo/2010-03-19-DbgDeclare.ll b/test/DebugInfo/2010-03-19-DbgDeclare.ll index a21c3619da2..9913a69053a 100644 --- a/test/DebugInfo/2010-03-19-DbgDeclare.ll +++ b/test/DebugInfo/2010-03-19-DbgDeclare.ll @@ -12,7 +12,7 @@ entry: !2 = !MDCompileUnit(language: DW_LANG_Mips_Assembler, producer: "clang version 3.3 ", isOptimized: false, emissionKind: 1, file: !4, enums: !3, retainedTypes: !3, subprograms: !3, globals: !3, imports: !3) !3 = !{} !0 = !MDLocation(line: 662302, column: 26, scope: !1) -!1 = !{i32 4, !"foo"} +!1 = !MDLocalVariable(tag: DW_TAG_auto_variable, name: "foo") !4 = !MDFile(filename: "scratch.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch") declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone diff --git a/test/Transforms/AddDiscriminators/no-discriminators.ll b/test/Transforms/AddDiscriminators/no-discriminators.ll index 87a74dd90eb..5ef0d00119c 100644 --- a/test/Transforms/AddDiscriminators/no-discriminators.ll +++ b/test/Transforms/AddDiscriminators/no-discriminators.ll @@ -17,7 +17,7 @@ entry: %retval = alloca i32, align 4 %i.addr = alloca i64, align 8 store i64 %i, i64* %i.addr, align 8 - call void @llvm.dbg.declare(metadata i64* %i.addr, metadata !13, metadata !{}), !dbg !14 + call void @llvm.dbg.declare(metadata i64* %i.addr, metadata !13, metadata !MDExpression()), !dbg !14 %0 = load i64, i64* %i.addr, align 8, !dbg !15 ; CHECK: %0 = load i64, i64* %i.addr, align 8, !dbg ![[ENTRY:[0-9]+]] %cmp = icmp slt i64 %0, 5, !dbg !15 diff --git a/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll b/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll index 75030ca4a1c..730a3f3eebf 100644 --- a/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll +++ b/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll @@ -4,10 +4,10 @@ define i8* @vfs_addname(i8* %name, i32 %len, i32 %hash, i32 %flags) nounwind ssp { entry: - call void @llvm.dbg.value(metadata i8* %name, i64 0, metadata !0, metadata !{}) - call void @llvm.dbg.value(metadata i32 %len, i64 0, metadata !10, metadata !{}) - call void @llvm.dbg.value(metadata i32 %hash, i64 0, metadata !11, metadata !{}) - call void @llvm.dbg.value(metadata i32 %flags, i64 0, metadata !12, metadata !{}) + call void @llvm.dbg.value(metadata i8* %name, i64 0, metadata !0, metadata !MDExpression()) + call void @llvm.dbg.value(metadata i32 %len, i64 0, metadata !10, metadata !MDExpression()) + call void @llvm.dbg.value(metadata i32 %hash, i64 0, metadata !11, metadata !MDExpression()) + call void @llvm.dbg.value(metadata i32 %flags, i64 0, metadata !12, metadata !MDExpression()) ; CHECK: call fastcc i8* @add_name_internal(i8* %name, i32 %hash) [[NUW:#[0-9]+]], !dbg !{{[0-9]+}} %0 = call fastcc i8* @add_name_internal(i8* %name, i32 %len, i32 %hash, i8 zeroext 0, i32 %flags) nounwind, !dbg !13 ; [#uses=1] ret i8* %0, !dbg !13 @@ -17,11 +17,11 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone define internal fastcc i8* @add_name_internal(i8* %name, i32 %len, i32 %hash, i8 zeroext %extra, i32 %flags) noinline nounwind ssp { entry: - call void @llvm.dbg.value(metadata i8* %name, i64 0, metadata !15, metadata !{}) - call void @llvm.dbg.value(metadata i32 %len, i64 0, metadata !20, metadata !{}) - call void @llvm.dbg.value(metadata i32 %hash, i64 0, metadata !21, metadata !{}) - call void @llvm.dbg.value(metadata i8 %extra, i64 0, metadata !22, metadata !{}) - call void @llvm.dbg.value(metadata i32 %flags, i64 0, metadata !23, metadata !{}) + call void @llvm.dbg.value(metadata i8* %name, i64 0, metadata !15, metadata !MDExpression()) + call void @llvm.dbg.value(metadata i32 %len, i64 0, metadata !20, metadata !MDExpression()) + call void @llvm.dbg.value(metadata i32 %hash, i64 0, metadata !21, metadata !MDExpression()) + call void @llvm.dbg.value(metadata i8 %extra, i64 0, metadata !22, metadata !MDExpression()) + call void @llvm.dbg.value(metadata i32 %flags, i64 0, metadata !23, metadata !MDExpression()) %0 = icmp eq i32 %hash, 0, !dbg !24 ; [#uses=1] br i1 %0, label %bb, label %bb1, !dbg !24 diff --git a/test/Transforms/DeadStoreElimination/inst-limits.ll b/test/Transforms/DeadStoreElimination/inst-limits.ll index 7a341e84ca8..14ba575abaa 100644 --- a/test/Transforms/DeadStoreElimination/inst-limits.ll +++ b/test/Transforms/DeadStoreElimination/inst-limits.ll @@ -118,7 +118,7 @@ entry: ; Insert a meaningless dbg.value intrinsic; it should have no ; effect on the working of DSE in any way. - call void @llvm.dbg.value(metadata i32* undef, i64 0, metadata !10, metadata !{}) + call void @llvm.dbg.value(metadata i32* undef, i64 0, metadata !10, metadata !MDExpression()) ; CHECK: store i32 -1, i32* @x, align 4 store i32 -1, i32* @x, align 4 @@ -255,7 +255,7 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) !7 = !{!8} !8 = !MDBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) !9 = !{!10} -!10 = !MDGlobalVariable(name: "x", line: 1, isLocal: false, isDefinition: true, scope: null, file: !5, type: !8, variable: i32* @x) +!10 = !MDLocalVariable(tag: DW_TAG_auto_variable, name: "x", scope: !4, type: !8) !11 = !{i32 2, !"Dwarf Version", i32 4} !12 = !{i32* undef} diff --git a/test/Transforms/GCOVProfiling/linezero.ll b/test/Transforms/GCOVProfiling/linezero.ll index 54c2c7c53a1..d56228255fb 100644 --- a/test/Transforms/GCOVProfiling/linezero.ll +++ b/test/Transforms/GCOVProfiling/linezero.ll @@ -18,17 +18,17 @@ entry: %__begin = alloca i8*, align 8 %__end = alloca i8*, align 8 %spec = alloca i8, align 1 - call void @llvm.dbg.declare(metadata %struct.vector** %__range, metadata !27, metadata !{}), !dbg !30 + call void @llvm.dbg.declare(metadata %struct.vector** %__range, metadata !27, metadata !MDExpression()), !dbg !30 br label %0 ;