[llvm] r228102 - [sanitizer] add another workaround for PR 17409: when over a threshold emit coverage instrumentation as calls.
Kostya Serebryany
kcc at google.com
Tue Feb 3 17:21:47 PST 2015
Author: kcc
Date: Tue Feb 3 19:21:45 2015
New Revision: 228102
URL: http://llvm.org/viewvc/llvm-project?rev=228102&view=rev
Log:
[sanitizer] add another workaround for PR 17409: when over a threshold emit coverage instrumentation as calls.
Modified:
llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll
Modified: llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp?rev=228102&r1=228101&r2=228102&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp Tue Feb 3 19:21:45 2015
@@ -55,6 +55,7 @@ using namespace llvm;
static const char *const kSanCovModuleInitName = "__sanitizer_cov_module_init";
static const char *const kSanCovName = "__sanitizer_cov";
+static const char *const kSanCovWithCheckName = "__sanitizer_cov_with_check";
static const char *const kSanCovIndirCallName = "__sanitizer_cov_indir_call16";
static const char *const kSanCovTraceEnter = "__sanitizer_cov_trace_func_enter";
static const char *const kSanCovTraceBB = "__sanitizer_cov_trace_basic_block";
@@ -67,11 +68,11 @@ static cl::opt<int> ClCoverageLevel("san
"4: above plus indirect calls"),
cl::Hidden, cl::init(0));
-static cl::opt<int> ClCoverageBlockThreshold(
+static cl::opt<unsigned> ClCoverageBlockThreshold(
"sanitizer-coverage-block-threshold",
- cl::desc("Add coverage instrumentation only to the entry block if there "
- "are more than this number of blocks."),
- cl::Hidden, cl::init(1500));
+ cl::desc("Use a callback with a guard check inside it if there are"
+ " more than this number of blocks."),
+ cl::Hidden, cl::init(1000));
static cl::opt<bool>
ClExperimentalTracing("sanitizer-coverage-experimental-tracing",
@@ -102,8 +103,9 @@ class SanitizerCoverageModule : public M
ArrayRef<Instruction *> IndirCalls);
bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks,
ArrayRef<Instruction *> IndirCalls);
- void InjectCoverageAtBlock(Function &F, BasicBlock &BB);
+ void InjectCoverageAtBlock(Function &F, BasicBlock &BB, bool UseCalls);
Function *SanCovFunction;
+ Function *SanCovWithCheckFunction;
Function *SanCovIndirCallFunction;
Function *SanCovModuleInit;
Function *SanCovTraceEnter, *SanCovTraceBB;
@@ -145,6 +147,8 @@ bool SanitizerCoverageModule::runOnModul
SanCovFunction = checkInterfaceFunction(
M.getOrInsertFunction(kSanCovName, VoidTy, Int32PtrTy, nullptr));
+ SanCovWithCheckFunction = checkInterfaceFunction(
+ M.getOrInsertFunction(kSanCovWithCheckName, VoidTy, Int32PtrTy, nullptr));
SanCovIndirCallFunction = checkInterfaceFunction(M.getOrInsertFunction(
kSanCovIndirCallName, VoidTy, IntptrTy, IntptrTy, nullptr));
SanCovModuleInit = checkInterfaceFunction(
@@ -221,12 +225,12 @@ SanitizerCoverageModule::InjectCoverage(
ArrayRef<Instruction *> IndirCalls) {
if (!CoverageLevel) return false;
- if (CoverageLevel == 1 ||
- (unsigned)ClCoverageBlockThreshold < AllBlocks.size()) {
- InjectCoverageAtBlock(F, F.getEntryBlock());
+ if (CoverageLevel == 1) {
+ InjectCoverageAtBlock(F, F.getEntryBlock(), false);
} else {
for (auto BB : AllBlocks)
- InjectCoverageAtBlock(F, *BB);
+ InjectCoverageAtBlock(F, *BB,
+ ClCoverageBlockThreshold < AllBlocks.size());
}
InjectCoverageForIndirectCalls(F, IndirCalls);
return true;
@@ -260,8 +264,8 @@ void SanitizerCoverageModule::InjectCove
}
}
-void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F,
- BasicBlock &BB) {
+void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
+ bool UseCalls) {
BasicBlock::iterator IP = BB.getFirstInsertionPt(), BE = BB.end();
// Skip static allocas at the top of the entry block so they don't become
// dynamic when we split the block. If we used our optimized stack layout,
@@ -283,19 +287,23 @@ void SanitizerCoverageModule::InjectCove
ConstantInt::get(IntptrTy, (1 + SanCovFunction->getNumUses()) * 4));
Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
GuardP = IRB.CreateIntToPtr(GuardP, Int32PtrTy);
- LoadInst *Load = IRB.CreateLoad(GuardP);
- Load->setAtomic(Monotonic);
- Load->setAlignment(4);
- Load->setMetadata(F.getParent()->getMDKindID("nosanitize"),
- MDNode::get(*C, None));
- Value *Cmp = IRB.CreateICmpSGE(Constant::getNullValue(Load->getType()), Load);
- Instruction *Ins = SplitBlockAndInsertIfThen(
- Cmp, IP, false, MDBuilder(*C).createBranchWeights(1, 100000));
- IRB.SetInsertPoint(Ins);
- IRB.SetCurrentDebugLocation(EntryLoc);
- // __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC.
- IRB.CreateCall(SanCovFunction, GuardP);
- IRB.CreateCall(EmptyAsm); // Avoids callback merge.
+ if (UseCalls) {
+ IRB.CreateCall(SanCovWithCheckFunction, GuardP);
+ } else {
+ LoadInst *Load = IRB.CreateLoad(GuardP);
+ Load->setAtomic(Monotonic);
+ Load->setAlignment(4);
+ Load->setMetadata(F.getParent()->getMDKindID("nosanitize"),
+ MDNode::get(*C, None));
+ Value *Cmp = IRB.CreateICmpSGE(Constant::getNullValue(Load->getType()), Load);
+ Instruction *Ins = SplitBlockAndInsertIfThen(
+ Cmp, IP, false, MDBuilder(*C).createBranchWeights(1, 100000));
+ IRB.SetInsertPoint(Ins);
+ IRB.SetCurrentDebugLocation(EntryLoc);
+ // __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC.
+ IRB.CreateCall(SanCovFunction, GuardP);
+ IRB.CreateCall(EmptyAsm); // Avoids callback merge.
+ }
if (ClExperimentalTracing) {
// Experimental support for tracing.
Modified: llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll?rev=228102&r1=228101&r2=228102&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll (original)
+++ llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll Tue Feb 3 19:21:45 2015
@@ -2,7 +2,7 @@
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -S | FileCheck %s --check-prefix=CHECK1
; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -S | FileCheck %s --check-prefix=CHECK2
; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -sanitizer-coverage-block-threshold=10 -S | FileCheck %s --check-prefix=CHECK2
-; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -sanitizer-coverage-block-threshold=1 -S | FileCheck %s --check-prefix=CHECK1
+; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -sanitizer-coverage-block-threshold=1 -S | FileCheck %s --check-prefix=CHECK_WITH_CHECK
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-block-threshold=10 -S | FileCheck %s --check-prefix=CHECK3
; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -S | FileCheck %s --check-prefix=CHECK4
@@ -12,7 +12,7 @@
; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -sanitizer-coverage-block-threshold=10 \
; RUN: -S | FileCheck %s --check-prefix=CHECK2
; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -sanitizer-coverage-block-threshold=1 \
-; RUN: -S | FileCheck %s --check-prefix=CHECK1
+; RUN: -S | FileCheck %s --check-prefix=CHECK_WITH_CHECK
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-unknown-linux-gnu"
@@ -50,6 +50,9 @@ entry:
; CHECK1: call void @__sanitizer_cov_module_init({{.*}}, i64 2)
; CHECK1: ret
+; CHECK_WITH_CHECK-LABEL: define void @foo
+; CHECK_WITH_CHECK: __sanitizer_cov_with_check
+; CHECK_WITH_CHECK: ret void
; CHECK2-LABEL: define void @foo
; CHECK2: call void @__sanitizer_cov
More information about the llvm-commits
mailing list