diff options
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp | 24 | ||||
-rw-r--r-- | llvm/test/Instrumentation/SanitizerCoverage/chains.ll | 27 |
2 files changed, 22 insertions, 29 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp index 2329cbf4d6b..4bc0a713311 100644 --- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -31,6 +31,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/EHPersonalities.h" +#include "llvm/Analysis/PostDominators.h" #include "llvm/IR/CFG.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/DataLayout.h" @@ -168,6 +169,7 @@ public: void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired<DominatorTreeWrapperPass>(); + AU.addRequired<PostDominatorTreeWrapperPass>(); } private: @@ -365,8 +367,23 @@ static bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) { return true; } +// True if block has predecessors and it postdominates all of them. +static bool isFullPostDominator(const BasicBlock *BB, + const PostDominatorTree *PDT) { + if (pred_begin(BB) == pred_end(BB)) + return false; + + for (const BasicBlock *PRED : make_range(pred_begin(BB), pred_end(BB))) { + if (!PDT->dominates(BB, PRED)) + return false; + } + + return true; +} + static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB, const DominatorTree *DT, + const PostDominatorTree *PDT, const SanitizerCoverageOptions &Options) { // Don't insert coverage for unreachable blocks: we will never call // __sanitizer_cov() for them, so counting them in @@ -384,7 +401,7 @@ static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB, if (Options.NoPrune || &F.getEntryBlock() == BB) return true; - return !isFullDominator(BB, DT); + return !(isFullDominator(BB, DT) || isFullPostDominator(BB, PDT)); } bool SanitizerCoverageModule::runOnFunction(Function &F) { @@ -416,9 +433,11 @@ bool SanitizerCoverageModule::runOnFunction(Function &F) { const DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>(F).getDomTree(); + const PostDominatorTree *PDT = + &getAnalysis<PostDominatorTreeWrapperPass>(F).getPostDomTree(); for (auto &BB : F) { - if (shouldInstrumentBlock(F, &BB, DT, Options)) + if (shouldInstrumentBlock(F, &BB, DT, PDT, Options)) BlocksToInstrument.push_back(&BB); for (auto &Inst : BB) { if (Options.IndirectCalls) { @@ -700,6 +719,7 @@ INITIALIZE_PASS_BEGIN(SanitizerCoverageModule, "sancov", "ModulePass", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) +INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass) INITIALIZE_PASS_END(SanitizerCoverageModule, "sancov", "SanitizerCoverage: TODO." "ModulePass", diff --git a/llvm/test/Instrumentation/SanitizerCoverage/chains.ll b/llvm/test/Instrumentation/SanitizerCoverage/chains.ll deleted file mode 100644 index 3cff4ecd8e8..00000000000 --- a/llvm/test/Instrumentation/SanitizerCoverage/chains.ll +++ /dev/null @@ -1,27 +0,0 @@ -; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s - -define i32 @blah(i32) #0 { - %2 = icmp sgt i32 %0, 1 - br i1 %2, label %branch, label %exit -; CHECK: call void @__sanitizer_cov_trace_pc() -branch: - br label %pos2 -; CHECK-LABEL: branch: -; CHECK-NOT: call void @__sanitizer_cov_trace_pc() -pos2: - br label %pos3 -; CHECK-LABEL: pos2: -; CHECK-NOT: call void @__sanitizer_cov_trace_pc() -pos3: - br label %pos4 -; CHECK-LABEL: pos3: -; CHECK-NOT: call void @__sanitizer_cov_trace_pc() -pos4: - ret i32 0 -; CHECK-LABEL: pos4: -; CHECK: call void @__sanitizer_cov_trace_pc() -exit: - ret i32 0 -; CHECK-LABEL: exit: -; CHECK: call void @__sanitizer_cov_trace_pc() -} |