[llvm] r221718 - Move asan-coverage into a separate phase.
Kostya Serebryany
kcc at google.com
Tue Nov 11 14:14:37 PST 2014
Author: kcc
Date: Tue Nov 11 16:14:37 2014
New Revision: 221718
URL: http://llvm.org/viewvc/llvm-project?rev=221718&view=rev
Log:
Move asan-coverage into a separate phase.
Summary:
This change moves asan-coverage instrumentation
into a separate Module pass.
The other part of the change in clang introduces a new flag
-fsanitize-coverage=N.
Another small patch will update tests in compiler-rt.
With this patch no functionality change is expected except for the flag name.
The following changes will make the coverage instrumentation work with tsan/msan
Test Plan: Run regression tests, chromium.
Reviewers: nlewycky, samsonov
Reviewed By: nlewycky, samsonov
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D6152
Added:
llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
llvm/trunk/test/Instrumentation/SanitizerCoverage/
llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage-dbg.ll
- copied, changed from r221717, llvm/trunk/test/Instrumentation/AddressSanitizer/coverage-dbg.ll
llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll
- copied, changed from r221378, llvm/trunk/test/Instrumentation/AddressSanitizer/coverage.ll
llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage2-dbg.ll
- copied, changed from r221378, llvm/trunk/test/Instrumentation/AddressSanitizer/coverage2-dbg.ll
Removed:
llvm/trunk/test/Instrumentation/AddressSanitizer/coverage-dbg.ll
llvm/trunk/test/Instrumentation/AddressSanitizer/coverage.ll
llvm/trunk/test/Instrumentation/AddressSanitizer/coverage2-dbg.ll
Modified:
llvm/trunk/include/llvm/InitializePasses.h
llvm/trunk/include/llvm/Transforms/Instrumentation.h
llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
llvm/trunk/lib/Transforms/Instrumentation/CMakeLists.txt
llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp
Modified: llvm/trunk/include/llvm/InitializePasses.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=221718&r1=221717&r2=221718&view=diff
==============================================================================
--- llvm/trunk/include/llvm/InitializePasses.h (original)
+++ llvm/trunk/include/llvm/InitializePasses.h Tue Nov 11 16:14:37 2014
@@ -126,6 +126,7 @@ void initializeAddressSanitizerPass(Pass
void initializeAddressSanitizerModulePass(PassRegistry&);
void initializeMemorySanitizerPass(PassRegistry&);
void initializeThreadSanitizerPass(PassRegistry&);
+void initializeSanitizerCoverageModulePass(PassRegistry&);
void initializeDataFlowSanitizerPass(PassRegistry&);
void initializeScalarizerPass(PassRegistry&);
void initializeEarlyCSEPass(PassRegistry&);
Modified: llvm/trunk/include/llvm/Transforms/Instrumentation.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Instrumentation.h?rev=221718&r1=221717&r2=221718&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Instrumentation.h (original)
+++ llvm/trunk/include/llvm/Transforms/Instrumentation.h Tue Nov 11 16:14:37 2014
@@ -78,6 +78,9 @@ ModulePass *createDataFlowSanitizerPass(
void *(*getArgTLS)() = nullptr,
void *(*getRetValTLS)() = nullptr);
+// Insert SanitizerCoverage instrumentation.
+ModulePass *createSanitizerCoverageModulePass(int CoverageLevel);
+
#if defined(__GNUC__) && defined(__linux__) && !defined(ANDROID)
inline ModulePass *createDataFlowSanitizerPassForJIT(StringRef ABIListFile =
StringRef()) {
Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=221718&r1=221717&r2=221718&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Tue Nov 11 16:14:37 2014
@@ -81,9 +81,6 @@ static const char *const kAsanUnregister
static const char *const kAsanPoisonGlobalsName = "__asan_before_dynamic_init";
static const char *const kAsanUnpoisonGlobalsName = "__asan_after_dynamic_init";
static const char *const kAsanInitName = "__asan_init_v4";
-static const char *const kAsanCovModuleInitName = "__sanitizer_cov_module_init";
-static const char *const kAsanCovName = "__sanitizer_cov";
-static const char *const kAsanCovIndirCallName = "__sanitizer_cov_indir_call16";
static const char *const kAsanPtrCmp = "__sanitizer_ptr_cmp";
static const char *const kAsanPtrSub = "__sanitizer_ptr_sub";
static const char *const kAsanHandleNoReturnName = "__asan_handle_no_return";
@@ -135,15 +132,6 @@ static cl::opt<bool> ClUseAfterReturn("a
// This flag may need to be replaced with -f[no]asan-globals.
static cl::opt<bool> ClGlobals("asan-globals",
cl::desc("Handle global objects"), cl::Hidden, cl::init(true));
-static cl::opt<int> ClCoverage("asan-coverage",
- cl::desc("ASan coverage. 0: none, 1: entry block, 2: all blocks, "
- "3: all blocks and critical edges, "
- "4: above plus indirect calls"),
- cl::Hidden, cl::init(false));
-static cl::opt<int> ClCoverageBlockThreshold("asan-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));
static cl::opt<bool> ClInitializers("asan-initialization-order",
cl::desc("Handle C++ initializer order"), cl::Hidden, cl::init(true));
static cl::opt<bool> ClInvalidPointerPairs("asan-detect-invalid-pointer-pair",
@@ -356,9 +344,7 @@ static size_t RedzoneSizeForScale(int Ma
/// AddressSanitizer: instrument the code in module to find memory bugs.
struct AddressSanitizer : public FunctionPass {
- AddressSanitizer() : FunctionPass(ID) {
- initializeBreakCriticalEdgesPass(*PassRegistry::getPassRegistry());
- }
+ AddressSanitizer() : FunctionPass(ID) {}
const char *getPassName() const override {
return "AddressSanitizerFunctionPass";
}
@@ -379,21 +365,11 @@ struct AddressSanitizer : public Functio
bool doInitialization(Module &M) override;
static char ID; // Pass identification, replacement for typeid
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- if (ClCoverage >= 3)
- AU.addRequiredID(BreakCriticalEdgesID);
- }
-
private:
void initializeCallbacks(Module &M);
bool LooksLikeCodeInBug11395(Instruction *I);
bool GlobalIsLinkerInitialized(GlobalVariable *G);
- void InjectCoverageForIndirectCalls(Function &F,
- ArrayRef<Instruction *> IndirCalls);
- bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks,
- ArrayRef<Instruction *> IndirCalls);
- void InjectCoverageAtBlock(Function &F, BasicBlock &BB);
LLVMContext *C;
const DataLayout *DL;
@@ -403,8 +379,6 @@ struct AddressSanitizer : public Functio
Function *AsanCtorFunction;
Function *AsanInitFunction;
Function *AsanHandleNoReturnFunc;
- Function *AsanCovFunction;
- Function *AsanCovIndirCallFunction;
Function *AsanPtrCmpFunction, *AsanPtrSubFunction;
// This array is indexed by AccessIsWrite and log2(AccessSize).
Function *AsanErrorCallback[2][kNumberOfAccessSizes];
@@ -448,7 +422,6 @@ class AddressSanitizerModule : public Mo
Function *AsanUnpoisonGlobals;
Function *AsanRegisterGlobals;
Function *AsanUnregisterGlobals;
- Function *AsanCovModuleInit;
};
// Stack poisoning does not play well with exception handling.
@@ -1037,10 +1010,6 @@ void AddressSanitizerModule::initializeC
kAsanUnregisterGlobalsName,
IRB.getVoidTy(), IntptrTy, IntptrTy, NULL));
AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage);
- AsanCovModuleInit = checkInterfaceFunction(M.getOrInsertFunction(
- kAsanCovModuleInitName,
- IRB.getVoidTy(), IntptrTy, NULL));
- AsanCovModuleInit->setLinkage(Function::ExternalLinkage);
}
// This function replaces all global variables with new variables that have
@@ -1198,13 +1167,6 @@ bool AddressSanitizerModule::runOnModule
assert(CtorFunc);
IRBuilder<> IRB(CtorFunc->getEntryBlock().getTerminator());
- if (ClCoverage > 0) {
- Function *CovFunc = M.getFunction(kAsanCovName);
- int nCov = CovFunc ? CovFunc->getNumUses() : 0;
- IRB.CreateCall(AsanCovModuleInit, ConstantInt::get(IntptrTy, nCov));
- Changed = true;
- }
-
if (ClGlobals)
Changed |= InstrumentGlobals(IRB, M);
@@ -1254,10 +1216,6 @@ void AddressSanitizer::initializeCallbac
AsanHandleNoReturnFunc = checkInterfaceFunction(
M.getOrInsertFunction(kAsanHandleNoReturnName, IRB.getVoidTy(), NULL));
- AsanCovFunction = checkInterfaceFunction(M.getOrInsertFunction(
- kAsanCovName, IRB.getVoidTy(), NULL));
- AsanCovIndirCallFunction = checkInterfaceFunction(M.getOrInsertFunction(
- kAsanCovIndirCallName, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL));
AsanPtrCmpFunction = checkInterfaceFunction(M.getOrInsertFunction(
kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL));
@@ -1316,105 +1274,6 @@ bool AddressSanitizer::maybeInsertAsanIn
return false;
}
-void AddressSanitizer::InjectCoverageAtBlock(Function &F, BasicBlock &BB) {
- 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,
- // then there will only be one alloca and it will come first.
- for (; IP != BE; ++IP) {
- AllocaInst *AI = dyn_cast<AllocaInst>(IP);
- if (!AI || !AI->isStaticAlloca())
- break;
- }
-
- DebugLoc EntryLoc = &BB == &F.getEntryBlock()
- ? IP->getDebugLoc().getFnDebugLoc(*C)
- : IP->getDebugLoc();
- IRBuilder<> IRB(IP);
- IRB.SetCurrentDebugLocation(EntryLoc);
- Type *Int8Ty = IRB.getInt8Ty();
- GlobalVariable *Guard = new GlobalVariable(
- *F.getParent(), Int8Ty, false, GlobalValue::PrivateLinkage,
- Constant::getNullValue(Int8Ty), "__asan_gen_cov_" + F.getName());
- LoadInst *Load = IRB.CreateLoad(Guard);
- Load->setAtomic(Monotonic);
- Load->setAlignment(1);
- Value *Cmp = IRB.CreateICmpEQ(Constant::getNullValue(Int8Ty), 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(AsanCovFunction);
- StoreInst *Store = IRB.CreateStore(ConstantInt::get(Int8Ty, 1), Guard);
- Store->setAtomic(Monotonic);
- Store->setAlignment(1);
-}
-
-// Poor man's coverage that works with ASan.
-// We create a Guard boolean variable with the same linkage
-// as the function and inject this code into the entry block (-asan-coverage=1)
-// or all blocks (-asan-coverage=2):
-// if (*Guard) {
-// __sanitizer_cov();
-// *Guard = 1;
-// }
-// The accesses to Guard are atomic. The rest of the logic is
-// in __sanitizer_cov (it's fine to call it more than once).
-//
-// This coverage implementation provides very limited data:
-// it only tells if a given function (block) was ever executed.
-// No counters, no per-edge data.
-// But for many use cases this is what we need and the added slowdown
-// is negligible. This simple implementation will probably be obsoleted
-// by the upcoming Clang-based coverage implementation.
-// By having it here and now we hope to
-// a) get the functionality to users earlier and
-// b) collect usage statistics to help improve Clang coverage design.
-bool AddressSanitizer::InjectCoverage(Function &F,
- ArrayRef<BasicBlock *> AllBlocks,
- ArrayRef<Instruction*> IndirCalls) {
- if (!ClCoverage) return false;
-
- if (ClCoverage == 1 ||
- (unsigned)ClCoverageBlockThreshold < AllBlocks.size()) {
- InjectCoverageAtBlock(F, F.getEntryBlock());
- } else {
- for (auto BB : AllBlocks)
- InjectCoverageAtBlock(F, *BB);
- }
- InjectCoverageForIndirectCalls(F, IndirCalls);
- return true;
-}
-
-// On every indirect call we call a run-time function
-// __sanitizer_cov_indir_call* with two parameters:
-// - callee address,
-// - global cache array that contains kCacheSize pointers (zero-initialed).
-// The cache is used to speed up recording the caller-callee pairs.
-// The address of the caller is passed implicitly via caller PC.
-// kCacheSize is encoded in the name of the run-time function.
-void AddressSanitizer::InjectCoverageForIndirectCalls(
- Function &F, ArrayRef<Instruction *> IndirCalls) {
- if (ClCoverage < 4 || IndirCalls.empty()) return;
- const int kCacheSize = 16;
- const int kCacheAlignment = 64; // Align for better performance.
- Type *Ty = ArrayType::get(IntptrTy, kCacheSize);
- for (auto I : IndirCalls) {
- IRBuilder<> IRB(I);
- CallSite CS(I);
- Value *Callee = CS.getCalledValue();
- if (dyn_cast<InlineAsm>(Callee)) continue;
- GlobalVariable *CalleeCache = new GlobalVariable(
- *F.getParent(), Ty, false, GlobalValue::PrivateLinkage,
- Constant::getNullValue(Ty), "__asan_gen_callee_cache");
- CalleeCache->setAlignment(kCacheAlignment);
- IRB.CreateCall2(AsanCovIndirCallFunction,
- IRB.CreatePointerCast(Callee, IntptrTy),
- IRB.CreatePointerCast(CalleeCache, IntptrTy));
- }
-}
-
bool AddressSanitizer::runOnFunction(Function &F) {
if (&F == AsanCtorFunction) return false;
if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return false;
@@ -1437,7 +1296,6 @@ bool AddressSanitizer::runOnFunction(Fun
SmallVector<Instruction*, 8> NoReturnCalls;
SmallVector<BasicBlock*, 16> AllBlocks;
SmallVector<Instruction*, 16> PointerComparisonsOrSubtracts;
- SmallVector<Instruction*, 8> IndirCalls;
int NumAllocas = 0;
bool IsWrite;
unsigned Alignment;
@@ -1470,8 +1328,6 @@ bool AddressSanitizer::runOnFunction(Fun
TempsToInstrument.clear();
if (CS.doesNotReturn())
NoReturnCalls.push_back(CS.getInstruction());
- if (ClCoverage >= 4 && !CS.getCalledFunction())
- IndirCalls.push_back(&Inst);
}
continue;
}
@@ -1528,9 +1384,6 @@ bool AddressSanitizer::runOnFunction(Fun
bool res = NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty();
- if (InjectCoverage(F, AllBlocks, IndirCalls))
- res = true;
-
DEBUG(dbgs() << "ASAN done instrumenting: " << res << " " << F << "\n");
if (ClKeepUninstrumented) {
Modified: llvm/trunk/lib/Transforms/Instrumentation/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/CMakeLists.txt?rev=221718&r1=221717&r2=221718&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/CMakeLists.txt (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/CMakeLists.txt Tue Nov 11 16:14:37 2014
@@ -6,6 +6,7 @@ add_llvm_library(LLVMInstrumentation
GCOVProfiling.cpp
MemorySanitizer.cpp
Instrumentation.cpp
+ SanitizerCoverage.cpp
ThreadSanitizer.cpp
)
Modified: llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp?rev=221718&r1=221717&r2=221718&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp Tue Nov 11 16:14:37 2014
@@ -27,6 +27,7 @@ void llvm::initializeInstrumentation(Pas
initializeGCOVProfilerPass(Registry);
initializeMemorySanitizerPass(Registry);
initializeThreadSanitizerPass(Registry);
+ initializeSanitizerCoverageModulePass(Registry);
initializeDataFlowSanitizerPass(Registry);
}
Added: llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp?rev=221718&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp (added)
+++ llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp Tue Nov 11 16:14:37 2014
@@ -0,0 +1,260 @@
+//===-- SanitizerCoverage.cpp - coverage instrumentation for sanitizers ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Coverage instrumentation that works with AddressSanitizer
+// and potentially with other Sanitizers.
+//
+// We create a Guard boolean variable with the same linkage
+// as the function and inject this code into the entry block (CoverageLevel=1)
+// or all blocks (CoverageLevel>=2):
+// if (*Guard) {
+// __sanitizer_cov();
+// *Guard = 1;
+// }
+// The accesses to Guard are atomic. The rest of the logic is
+// in __sanitizer_cov (it's fine to call it more than once).
+//
+// With CoverageLevel>=3 we also split critical edges this effectively
+// instrumenting all edges.
+//
+// CoverageLevel>=4 add indirect call profiling implented as a function call.
+//
+// This coverage implementation provides very limited data:
+// it only tells if a given function (block) was ever executed. No counters.
+// But for many use cases this is what we need and the added slowdown small.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "sancov"
+
+static const char *const kSanCovModuleInitName = "__sanitizer_cov_module_init";
+static const char *const kSanCovName = "__sanitizer_cov";
+static const char *const kSanCovIndirCallName = "__sanitizer_cov_indir_call16";
+static const char *const kSanCovModuleCtorName = "sancov.module_ctor";
+static const uint64_t kSanCtorAndDtorPriority = 1;
+
+static cl::opt<int> ClCoverageLevel("sanitizer-coverage-level",
+ cl::desc("Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, "
+ "3: all blocks and critical edges, "
+ "4: above plus indirect calls"),
+ cl::Hidden, cl::init(0));
+
+static cl::opt<int> 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));
+
+namespace {
+
+class SanitizerCoverageModule : public ModulePass {
+ public:
+ SanitizerCoverageModule(int CoverageLevel = 0)
+ : ModulePass(ID),
+ CoverageLevel(std::max(CoverageLevel, (int)ClCoverageLevel)) {
+ initializeBreakCriticalEdgesPass(*PassRegistry::getPassRegistry());
+ }
+ bool runOnModule(Module &M) override;
+ bool runOnFunction(Function &F);
+ static char ID; // Pass identification, replacement for typeid
+ const char *getPassName() const override {
+ return "SanitizerCoverageModule";
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ if (CoverageLevel >= 3)
+ AU.addRequiredID(BreakCriticalEdgesID);
+ AU.addRequired<DataLayoutPass>();
+ }
+
+ private:
+ void InjectCoverageForIndirectCalls(Function &F,
+ ArrayRef<Instruction *> IndirCalls);
+ bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks,
+ ArrayRef<Instruction *> IndirCalls);
+ void InjectCoverageAtBlock(Function &F, BasicBlock &BB);
+ Function *SanCovFunction;
+ Function *SanCovIndirCallFunction;
+ Function *SanCovModuleInit;
+ Type *IntptrTy;
+ LLVMContext *C;
+
+ int CoverageLevel;
+};
+
+} // namespace
+
+static Function *checkInterfaceFunction(Constant *FuncOrBitcast) {
+ if (Function *F = dyn_cast<Function>(FuncOrBitcast))
+ return F;
+ std::string Err;
+ raw_string_ostream Stream(Err);
+ Stream << "SanitizerCoverage interface function redefined: "
+ << *FuncOrBitcast;
+ report_fatal_error(Err);
+}
+
+bool SanitizerCoverageModule::runOnModule(Module &M) {
+ if (!CoverageLevel) return false;
+ C = &(M.getContext());
+ DataLayoutPass *DLP = &getAnalysis<DataLayoutPass>();
+ IntptrTy = Type::getIntNTy(*C, DLP->getDataLayout().getPointerSizeInBits());
+ Type *VoidTy = Type::getVoidTy(*C);
+
+ Function *CtorFunc =
+ Function::Create(FunctionType::get(VoidTy, false),
+ GlobalValue::InternalLinkage, kSanCovModuleCtorName, &M);
+ ReturnInst::Create(*C, BasicBlock::Create(*C, "", CtorFunc));
+ appendToGlobalCtors(M, CtorFunc, kSanCtorAndDtorPriority);
+
+ SanCovFunction =
+ checkInterfaceFunction(M.getOrInsertFunction(kSanCovName, VoidTy, NULL));
+ SanCovIndirCallFunction = checkInterfaceFunction(M.getOrInsertFunction(
+ kSanCovIndirCallName, VoidTy, IntptrTy, IntptrTy, NULL));
+ SanCovModuleInit = checkInterfaceFunction(M.getOrInsertFunction(
+ kSanCovModuleInitName, Type::getVoidTy(*C), IntptrTy, NULL));
+ SanCovModuleInit->setLinkage(Function::ExternalLinkage);
+
+ for (auto &F : M)
+ runOnFunction(F);
+
+ IRBuilder<> IRB(CtorFunc->getEntryBlock().getTerminator());
+ IRB.CreateCall(SanCovModuleInit,
+ ConstantInt::get(IntptrTy, SanCovFunction->getNumUses()));
+ return true;
+}
+
+bool SanitizerCoverageModule::runOnFunction(Function &F) {
+ if (F.empty()) return false;
+ // For now instrument only functions that will also be asan-instrumented.
+ if (!F.hasFnAttribute(Attribute::SanitizeAddress))
+ return false;
+ SmallVector<Instruction*, 8> IndirCalls;
+ SmallVector<BasicBlock*, 16> AllBlocks;
+ for (auto &BB : F) {
+ AllBlocks.push_back(&BB);
+ if (CoverageLevel >= 4)
+ for (auto &Inst : BB) {
+ CallSite CS(&Inst);
+ if (CS && !CS.getCalledFunction())
+ IndirCalls.push_back(&Inst);
+ }
+ }
+ InjectCoverage(F, AllBlocks, IndirCalls);
+ return true;
+}
+
+bool
+SanitizerCoverageModule::InjectCoverage(Function &F,
+ ArrayRef<BasicBlock *> AllBlocks,
+ ArrayRef<Instruction *> IndirCalls) {
+ if (!CoverageLevel) return false;
+
+ if (CoverageLevel == 1 ||
+ (unsigned)ClCoverageBlockThreshold < AllBlocks.size()) {
+ InjectCoverageAtBlock(F, F.getEntryBlock());
+ } else {
+ for (auto BB : AllBlocks)
+ InjectCoverageAtBlock(F, *BB);
+ }
+ InjectCoverageForIndirectCalls(F, IndirCalls);
+ return true;
+}
+
+// On every indirect call we call a run-time function
+// __sanitizer_cov_indir_call* with two parameters:
+// - callee address,
+// - global cache array that contains kCacheSize pointers (zero-initialized).
+// The cache is used to speed up recording the caller-callee pairs.
+// The address of the caller is passed implicitly via caller PC.
+// kCacheSize is encoded in the name of the run-time function.
+void SanitizerCoverageModule::InjectCoverageForIndirectCalls(
+ Function &F, ArrayRef<Instruction *> IndirCalls) {
+ if (IndirCalls.empty()) return;
+ const int kCacheSize = 16;
+ const int kCacheAlignment = 64; // Align for better performance.
+ Type *Ty = ArrayType::get(IntptrTy, kCacheSize);
+ for (auto I : IndirCalls) {
+ IRBuilder<> IRB(I);
+ CallSite CS(I);
+ Value *Callee = CS.getCalledValue();
+ if (dyn_cast<InlineAsm>(Callee)) continue;
+ GlobalVariable *CalleeCache = new GlobalVariable(
+ *F.getParent(), Ty, false, GlobalValue::PrivateLinkage,
+ Constant::getNullValue(Ty), "__sancov_gen_callee_cache");
+ CalleeCache->setAlignment(kCacheAlignment);
+ IRB.CreateCall2(SanCovIndirCallFunction,
+ IRB.CreatePointerCast(Callee, IntptrTy),
+ IRB.CreatePointerCast(CalleeCache, IntptrTy));
+ }
+}
+
+void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F,
+ BasicBlock &BB) {
+ 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,
+ // then there will only be one alloca and it will come first.
+ for (; IP != BE; ++IP) {
+ AllocaInst *AI = dyn_cast<AllocaInst>(IP);
+ if (!AI || !AI->isStaticAlloca())
+ break;
+ }
+
+ DebugLoc EntryLoc = &BB == &F.getEntryBlock()
+ ? IP->getDebugLoc().getFnDebugLoc(*C)
+ : IP->getDebugLoc();
+ IRBuilder<> IRB(IP);
+ IRB.SetCurrentDebugLocation(EntryLoc);
+ Type *Int8Ty = IRB.getInt8Ty();
+ GlobalVariable *Guard = new GlobalVariable(
+ *F.getParent(), Int8Ty, false, GlobalValue::PrivateLinkage,
+ Constant::getNullValue(Int8Ty), "__sancov_gen_cov_" + F.getName());
+ LoadInst *Load = IRB.CreateLoad(Guard);
+ Load->setAtomic(Monotonic);
+ Load->setAlignment(1);
+ Value *Cmp = IRB.CreateICmpEQ(Constant::getNullValue(Int8Ty), 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);
+ StoreInst *Store = IRB.CreateStore(ConstantInt::get(Int8Ty, 1), Guard);
+ Store->setAtomic(Monotonic);
+ Store->setAlignment(1);
+}
+
+char SanitizerCoverageModule::ID = 0;
+INITIALIZE_PASS(SanitizerCoverageModule, "sancov",
+ "SanitizerCoverage: TODO."
+ "ModulePass", false, false)
+ModulePass *llvm::createSanitizerCoverageModulePass(int CoverageLevel) {
+ return new SanitizerCoverageModule(CoverageLevel);
+}
Removed: llvm/trunk/test/Instrumentation/AddressSanitizer/coverage-dbg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/coverage-dbg.ll?rev=221717&view=auto
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/coverage-dbg.ll (original)
+++ llvm/trunk/test/Instrumentation/AddressSanitizer/coverage-dbg.ll (removed)
@@ -1,67 +0,0 @@
-; Test that coverage instrumentation does not lose debug location.
-
-; RUN: opt < %s -asan -asan-module -asan-coverage=1 -S | FileCheck %s
-
-; C++ source:
-; 1: struct A {
-; 2: int f();
-; 3: int x;
-; 4: };
-; 5:
-; 6: int A::f() {
-; 7: return x;
-; 8: }
-; clang++ ../1.cc -O3 -g -S -emit-llvm -fno-strict-aliasing
-; and add sanitize_address to @_ZN1A1fEv
-
-; Test that __sanitizer_cov call has !dbg pointing to the opening { of A::f().
-; CHECK: call void @__sanitizer_cov(), !dbg [[A:!.*]]
-; CHECK: [[A]] = metadata !{i32 6, i32 0, metadata !{{.*}}, null}
-
-
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-unknown-linux-gnu"
-
-%struct.A = type { i32 }
-
-; Function Attrs: nounwind readonly uwtable
-define i32 @_ZN1A1fEv(%struct.A* nocapture readonly %this) #0 align 2 {
-entry:
- tail call void @llvm.dbg.value(metadata !{%struct.A* %this}, i64 0, metadata !15, metadata !{metadata !"0x102"}), !dbg !20
- %x = getelementptr inbounds %struct.A* %this, i64 0, i32 0, !dbg !21
- %0 = load i32* %x, align 4, !dbg !21
- ret i32 %0, !dbg !21
-}
-
-; Function Attrs: nounwind readnone
-declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1
-
-attributes #0 = { sanitize_address nounwind readonly uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
-attributes #1 = { nounwind readnone }
-
-!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!17, !18}
-!llvm.ident = !{!19}
-
-!0 = metadata !{metadata !"0x11\004\00clang version 3.5.0 (210251)\001\00\000\00\001", metadata !1, metadata !2, metadata !3, metadata !12, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [/code/llvm/build0/../1.cc] [DW_LANG_C_plus_plus]
-!1 = metadata !{metadata !"../1.cc", metadata !"/code/llvm/build0"}
-!2 = metadata !{}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x13\00A\001\0032\0032\000\000\000", metadata !1, null, null, metadata !5, null, null, metadata !"_ZTS1A"} ; [ DW_TAG_structure_type ] [A] [line 1, size 32, align 32, offset 0] [def] [from ]
-!5 = metadata !{metadata !6, metadata !8}
-!6 = metadata !{metadata !"0xd\00x\003\0032\0032\000\000", metadata !1, metadata !"_ZTS1A", metadata !7} ; [ DW_TAG_member ] [x] [line 3, size 32, align 32, offset 0] [from int]
-!7 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
-!8 = metadata !{metadata !"0x2e\00f\00f\00_ZN1A1fEv\002\000\000\000\006\00256\001\002", metadata !1, metadata !"_ZTS1A", metadata !9, null, null, null, i32 0, null} ; [ DW_TAG_subprogram ] [line 2] [f]
-!9 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !10, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!10 = metadata !{metadata !7, metadata !11}
-!11 = metadata !{metadata !"0xf\00\000\0064\0064\000\001088", null, null, metadata !"_ZTS1A"} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from _ZTS1A]
-!12 = metadata !{metadata !13}
-!13 = metadata !{metadata !"0x2e\00f\00f\00_ZN1A1fEv\006\000\001\000\006\00256\001\006", metadata !1, metadata !"_ZTS1A", metadata !9, null, i32 (%struct.A*)* @_ZN1A1fEv, null, metadata !8, metadata !14} ; [ DW_TAG_subprogram ] [line 6] [def] [f]
-!14 = metadata !{metadata !15}
-!15 = metadata !{metadata !"0x101\00this\0016777216\001088", metadata !13, null, metadata !16} ; [ DW_TAG_arg_variable ] [this] [line 0]
-!16 = metadata !{metadata !"0xf\00\000\0064\0064\000\000", null, null, metadata !"_ZTS1A"} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from _ZTS1A]
-!17 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!18 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
-!19 = metadata !{metadata !"clang version 3.5.0 (210251)"}
-!20 = metadata !{i32 0, i32 0, metadata !13, null}
-!21 = metadata !{i32 7, i32 0, metadata !13, null}
Removed: llvm/trunk/test/Instrumentation/AddressSanitizer/coverage.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/coverage.ll?rev=221717&view=auto
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/coverage.ll (original)
+++ llvm/trunk/test/Instrumentation/AddressSanitizer/coverage.ll (removed)
@@ -1,91 +0,0 @@
-; RUN: opt < %s -asan -asan-module -asan-coverage=0 -S | FileCheck %s --check-prefix=CHECK0
-; RUN: opt < %s -asan -asan-module -asan-coverage=1 -S | FileCheck %s --check-prefix=CHECK1
-; RUN: opt < %s -asan -asan-module -asan-coverage=2 -S | FileCheck %s --check-prefix=CHECK2
-; RUN: opt < %s -asan -asan-module -asan-coverage=2 -asan-coverage-block-threshold=10 -S | FileCheck %s --check-prefix=CHECK2
-; RUN: opt < %s -asan -asan-module -asan-coverage=2 -asan-coverage-block-threshold=1 -S | FileCheck %s --check-prefix=CHECK1
-; RUN: opt < %s -asan -asan-module -asan-coverage=3 -asan-coverage-block-threshold=10 -S | FileCheck %s --check-prefix=CHECK3
-; RUN: opt < %s -asan -asan-module -asan-coverage=4 -S | FileCheck %s --check-prefix=CHECK4
-
-; RUN: opt < %s -asan -asan-module -asan-coverage=0 -asan-globals=0 -S | \
-; RUN: FileCheck %s --check-prefix=CHECK0
-; RUN: opt < %s -asan -asan-module -asan-coverage=1 -asan-globals=0 -S | \
-; RUN: FileCheck %s --check-prefix=CHECK1
-; RUN: opt < %s -asan -asan-module -asan-coverage=2 -asan-globals=0 -S | \
-; RUN: FileCheck %s --check-prefix=CHECK2
-; RUN: opt < %s -asan -asan-module -asan-coverage=2 -asan-coverage-block-threshold=10 \
-; RUN: -asan-globals=0 -S | FileCheck %s --check-prefix=CHECK2
-; RUN: opt < %s -asan -asan-module -asan-coverage=2 -asan-coverage-block-threshold=1 \
-; RUN: -asan-globals=0 -S | FileCheck %s --check-prefix=CHECK1
-
-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"
-define void @foo(i32* %a) sanitize_address {
-entry:
- %tobool = icmp eq i32* %a, null
- br i1 %tobool, label %if.end, label %if.then
-
- if.then: ; preds = %entry
- store i32 0, i32* %a, align 4
- br label %if.end
-
- if.end: ; preds = %entry, %if.then
- ret void
-}
-
-; CHECK0-NOT: call void @__sanitizer_cov(
-; CHECK0-NOT: call void @__sanitizer_cov_module_init(
-
-; CHECK1-LABEL: define void @foo
-; CHECK1: %0 = load atomic i8* @__asan_gen_cov_foo monotonic, align 1
-; CHECK1: %1 = icmp eq i8 0, %0
-; CHECK1: br i1 %1, label %2, label %3
-; CHECK1: call void @__sanitizer_cov
-; CHECK1-NOT: call void @__sanitizer_cov
-; CHECK1: store atomic i8 1, i8* @__asan_gen_cov_foo monotonic, align 1
-
-; CHECK1-LABEL: define internal void @asan.module_ctor
-; CHECK1-NOT: ret
-; CHECK1: call void @__sanitizer_cov_module_init(i64 2)
-; CHECK1: ret
-
-
-; CHECK2-LABEL: define void @foo
-; CHECK2: call void @__sanitizer_cov
-; CHECK2: call void @__sanitizer_cov
-; CHECK2: call void @__sanitizer_cov
-; CHECK2-NOT: call void @__sanitizer_cov
-; CHECK2: ret void
-
-; CHECK2-LABEL: define internal void @asan.module_ctor
-; CHECK2-NOT: ret
-; CHECK2: call void @__sanitizer_cov_module_init(i64 4)
-; CHECK2: ret
-
-; CHECK3-LABEL: define void @foo
-; CHECK3: call void @__sanitizer_cov
-; CHECK3: call void @__sanitizer_cov
-; CHECK3: call void @__sanitizer_cov
-; CHECK3: call void @__sanitizer_cov
-; CHECK3-NOT: call void @__sanitizer_cov
-; CHECK3: ret void
-
-
-%struct.StructWithVptr = type { i32 (...)** }
-
-define void @CallViaVptr(%struct.StructWithVptr* %foo) uwtable sanitize_address {
-entry:
- %0 = bitcast %struct.StructWithVptr* %foo to void (%struct.StructWithVptr*)***
- %vtable = load void (%struct.StructWithVptr*)*** %0, align 8
- %1 = load void (%struct.StructWithVptr*)** %vtable, align 8
- tail call void %1(%struct.StructWithVptr* %foo)
- tail call void %1(%struct.StructWithVptr* %foo)
- tail call void asm sideeffect "", ""()
- ret void
-}
-
-; We expect to see two calls to __sanitizer_cov_indir_call16
-; with different values of second argument.
-; CHECK4-LABEL: define void @CallViaVptr
-; CHECK4: call void @__sanitizer_cov_indir_call16({{.*}},[[CACHE:.*]])
-; CHECK4-NOT: call void @__sanitizer_cov_indir_call16({{.*}},[[CACHE]])
-; CHECK4: ret void
Removed: llvm/trunk/test/Instrumentation/AddressSanitizer/coverage2-dbg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/coverage2-dbg.ll?rev=221717&view=auto
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/coverage2-dbg.ll (original)
+++ llvm/trunk/test/Instrumentation/AddressSanitizer/coverage2-dbg.ll (removed)
@@ -1,75 +0,0 @@
-; Test that coverage instrumentation does not lose debug location.
-
-; RUN: opt < %s -asan -asan-module -asan-coverage=2 -S | FileCheck %s
-
-; C++ source:
-; 1: void foo(int *a) {
-; 2: if (a)
-; 3: *a = 0;
-; 4: }
-; clang++ if.cc -O3 -g -S -emit-llvm
-; and add sanitize_address to @_Z3fooPi
-
-
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-unknown-linux-gnu"
-
-; Check that __sanitizer_cov call has !dgb pointing to the beginning
-; of appropriate basic blocks.
-; CHECK-LABEL:_Z3fooPi
-; CHECK: call void @__sanitizer_cov(), !dbg [[A:!.*]]
-; CHECK: call void @__sanitizer_cov(), !dbg [[B:!.*]]
-; CHECK: call void @__sanitizer_cov(), !dbg [[C:!.*]]
-; CHECK: ret void
-; CHECK: [[A]] = metadata !{i32 1, i32 0, metadata !{{.*}}, null}
-; CHECK: [[B]] = metadata !{i32 3, i32 5, metadata !{{.*}}, null}
-; CHECK: [[C]] = metadata !{i32 4, i32 1, metadata !{{.*}}, null}
-
-define void @_Z3fooPi(i32* %a) #0 {
-entry:
- tail call void @llvm.dbg.value(metadata !{i32* %a}, i64 0, metadata !11, metadata !{metadata !"0x102"}), !dbg !15
- %tobool = icmp eq i32* %a, null, !dbg !16
- br i1 %tobool, label %if.end, label %if.then, !dbg !16
-
-if.then: ; preds = %entry
- store i32 0, i32* %a, align 4, !dbg !18, !tbaa !19
- br label %if.end, !dbg !18
-
-if.end: ; preds = %entry, %if.then
- ret void, !dbg !23
-}
-
-; Function Attrs: nounwind readnone
-declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1
-
-attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" sanitize_address}
-attributes #1 = { nounwind readnone }
-
-!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!12, !13}
-!llvm.ident = !{!14}
-
-!0 = metadata !{metadata !"0x11\004\00clang version 3.6.0 (217079)\001\00\000\00\001", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [FOO/if.cc] [DW_LANG_C_plus_plus]
-!1 = metadata !{metadata !"if.cc", metadata !"FOO"}
-!2 = metadata !{}
-!3 = metadata !{metadata !4}
-!4 = metadata !{metadata !"0x2e\00foo\00foo\00_Z3fooPi\001\000\001\000\006\00256\001\001", metadata !1, metadata !5, metadata !6, null, void (i32*)* @_Z3fooPi, null, null, metadata !10} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
-!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [FOO/if.cc]
-!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!7 = metadata !{null, metadata !8}
-!8 = metadata !{metadata !"0xf\00\000\0064\0064\000\000", null, null, metadata !9} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from int]
-!9 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
-!10 = metadata !{metadata !11}
-!11 = metadata !{metadata !"0x101\00a\0016777217\000", metadata !4, metadata !5, metadata !8} ; [ DW_TAG_arg_variable ] [a] [line 1]
-!12 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!13 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
-!14 = metadata !{metadata !"clang version 3.6.0 (217079)"}
-!15 = metadata !{i32 1, i32 15, metadata !4, null}
-!16 = metadata !{i32 2, i32 7, metadata !17, null}
-!17 = metadata !{metadata !"0xb\002\007\000", metadata !1, metadata !4} ; [ DW_TAG_lexical_block ] [FOO/if.cc]
-!18 = metadata !{i32 3, i32 5, metadata !17, null}
-!19 = metadata !{metadata !20, metadata !20, i64 0}
-!20 = metadata !{metadata !"int", metadata !21, i64 0}
-!21 = metadata !{metadata !"omnipotent char", metadata !22, i64 0}
-!22 = metadata !{metadata !"Simple C/C++ TBAA"}
-!23 = metadata !{i32 4, i32 1, metadata !4, null}
Copied: llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage-dbg.ll (from r221717, llvm/trunk/test/Instrumentation/AddressSanitizer/coverage-dbg.ll)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage-dbg.ll?p2=llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage-dbg.ll&p1=llvm/trunk/test/Instrumentation/AddressSanitizer/coverage-dbg.ll&r1=221717&r2=221718&rev=221718&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/coverage-dbg.ll (original)
+++ llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage-dbg.ll Tue Nov 11 16:14:37 2014
@@ -1,6 +1,6 @@
; Test that coverage instrumentation does not lose debug location.
-; RUN: opt < %s -asan -asan-module -asan-coverage=1 -S | FileCheck %s
+; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -S | FileCheck %s
; C++ source:
; 1: struct A {
Copied: llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll (from r221378, llvm/trunk/test/Instrumentation/AddressSanitizer/coverage.ll)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll?p2=llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll&p1=llvm/trunk/test/Instrumentation/AddressSanitizer/coverage.ll&r1=221378&r2=221718&rev=221718&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/coverage.ll (original)
+++ llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll Tue Nov 11 16:14:37 2014
@@ -1,21 +1,18 @@
-; RUN: opt < %s -asan -asan-module -asan-coverage=0 -S | FileCheck %s --check-prefix=CHECK0
-; RUN: opt < %s -asan -asan-module -asan-coverage=1 -S | FileCheck %s --check-prefix=CHECK1
-; RUN: opt < %s -asan -asan-module -asan-coverage=2 -S | FileCheck %s --check-prefix=CHECK2
-; RUN: opt < %s -asan -asan-module -asan-coverage=2 -asan-coverage-block-threshold=10 -S | FileCheck %s --check-prefix=CHECK2
-; RUN: opt < %s -asan -asan-module -asan-coverage=2 -asan-coverage-block-threshold=1 -S | FileCheck %s --check-prefix=CHECK1
-; RUN: opt < %s -asan -asan-module -asan-coverage=3 -asan-coverage-block-threshold=10 -S | FileCheck %s --check-prefix=CHECK3
-; RUN: opt < %s -asan -asan-module -asan-coverage=4 -S | FileCheck %s --check-prefix=CHECK4
-
-; RUN: opt < %s -asan -asan-module -asan-coverage=0 -asan-globals=0 -S | \
-; RUN: FileCheck %s --check-prefix=CHECK0
-; RUN: opt < %s -asan -asan-module -asan-coverage=1 -asan-globals=0 -S | \
-; RUN: FileCheck %s --check-prefix=CHECK1
-; RUN: opt < %s -asan -asan-module -asan-coverage=2 -asan-globals=0 -S | \
-; RUN: FileCheck %s --check-prefix=CHECK2
-; RUN: opt < %s -asan -asan-module -asan-coverage=2 -asan-coverage-block-threshold=10 \
-; RUN: -asan-globals=0 -S | FileCheck %s --check-prefix=CHECK2
-; RUN: opt < %s -asan -asan-module -asan-coverage=2 -asan-coverage-block-threshold=1 \
-; RUN: -asan-globals=0 -S | FileCheck %s --check-prefix=CHECK1
+; RUN: opt < %s -sancov -sanitizer-coverage-level=0 -S | FileCheck %s --check-prefix=CHECK0
+; 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=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
+
+; RUN: opt < %s -sancov -sanitizer-coverage-level=0 -S | FileCheck %s --check-prefix=CHECK0
+; 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 \
+; 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
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"
@@ -36,14 +33,14 @@ entry:
; CHECK0-NOT: call void @__sanitizer_cov_module_init(
; CHECK1-LABEL: define void @foo
-; CHECK1: %0 = load atomic i8* @__asan_gen_cov_foo monotonic, align 1
+; CHECK1: %0 = load atomic i8* @__sancov_gen_cov_foo monotonic, align 1
; CHECK1: %1 = icmp eq i8 0, %0
; CHECK1: br i1 %1, label %2, label %3
; CHECK1: call void @__sanitizer_cov
; CHECK1-NOT: call void @__sanitizer_cov
-; CHECK1: store atomic i8 1, i8* @__asan_gen_cov_foo monotonic, align 1
+; CHECK1: store atomic i8 1, i8* @__sancov_gen_cov_foo monotonic, align 1
-; CHECK1-LABEL: define internal void @asan.module_ctor
+; CHECK1-LABEL: define internal void @sancov.module_ctor
; CHECK1-NOT: ret
; CHECK1: call void @__sanitizer_cov_module_init(i64 2)
; CHECK1: ret
@@ -56,7 +53,7 @@ entry:
; CHECK2-NOT: call void @__sanitizer_cov
; CHECK2: ret void
-; CHECK2-LABEL: define internal void @asan.module_ctor
+; CHECK2-LABEL: define internal void @sancov.module_ctor
; CHECK2-NOT: ret
; CHECK2: call void @__sanitizer_cov_module_init(i64 4)
; CHECK2: ret
Copied: llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage2-dbg.ll (from r221378, llvm/trunk/test/Instrumentation/AddressSanitizer/coverage2-dbg.ll)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage2-dbg.ll?p2=llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage2-dbg.ll&p1=llvm/trunk/test/Instrumentation/AddressSanitizer/coverage2-dbg.ll&r1=221378&r2=221718&rev=221718&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/coverage2-dbg.ll (original)
+++ llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage2-dbg.ll Tue Nov 11 16:14:37 2014
@@ -1,6 +1,6 @@
; Test that coverage instrumentation does not lose debug location.
-; RUN: opt < %s -asan -asan-module -asan-coverage=2 -S | FileCheck %s
+; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -S | FileCheck %s
; C++ source:
; 1: void foo(int *a) {
More information about the llvm-commits
mailing list