From 7376294086db699ad8881cc9e0fdb18ab2e1ab0d Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Tue, 16 Dec 2014 21:24:15 +0000 Subject: [PATCH] [sanitizer] prevent function call merging for sanitizer-coverage callbacks llvm-svn: 224372 --- llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp | 7 +++++++ llvm/test/Instrumentation/SanitizerCoverage/coverage.ll | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp index 7d86e1c8af06..07223d4df5c0 100644 --- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -37,6 +37,7 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" +#include "llvm/IR/InlineAsm.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Module.h" @@ -107,6 +108,7 @@ class SanitizerCoverageModule : public ModulePass { Function *SanCovIndirCallFunction; Function *SanCovModuleInit; Function *SanCovTraceEnter, *SanCovTraceBB; + InlineAsm *EmptyAsm; Type *IntptrTy; LLVMContext *C; @@ -146,6 +148,10 @@ bool SanitizerCoverageModule::runOnModule(Module &M) { SanCovModuleInit = checkInterfaceFunction(M.getOrInsertFunction( kSanCovModuleInitName, Type::getVoidTy(*C), IntptrTy, nullptr)); SanCovModuleInit->setLinkage(Function::ExternalLinkage); + // We insert an empty inline asm after cov callbacks to avoid callback merge. + EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), + StringRef(""), StringRef(""), + /*hasSideEffects=*/true); if (ClExperimentalTracing) { SanCovTraceEnter = checkInterfaceFunction( @@ -283,6 +289,7 @@ void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, IRB.SetCurrentDebugLocation(EntryLoc); // __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC. IRB.CreateCall(SanCovFunction, Guard); + IRB.CreateCall(EmptyAsm); // Avoids callback merge. } char SanitizerCoverageModule::ID = 0; diff --git a/llvm/test/Instrumentation/SanitizerCoverage/coverage.ll b/llvm/test/Instrumentation/SanitizerCoverage/coverage.ll index aa3ba5c72028..68e7fc0ef320 100644 --- a/llvm/test/Instrumentation/SanitizerCoverage/coverage.ll +++ b/llvm/test/Instrumentation/SanitizerCoverage/coverage.ll @@ -37,6 +37,7 @@ entry: ; CHECK1: %1 = icmp eq i8 0, %0 ; CHECK1: br i1 %1, label %2, label %3 ; CHECK1: call void @__sanitizer_cov(i8*{{.*}}) +; CHECK1: call void asm sideeffect "", ""() ; CHECK1-NOT: call void @__sanitizer_cov ; CHECK1: ret void @@ -48,8 +49,11 @@ entry: ; CHECK2-LABEL: define void @foo ; CHECK2: call void @__sanitizer_cov +; CHECK2: call void asm sideeffect "", ""() ; CHECK2: call void @__sanitizer_cov +; CHECK2: call void asm sideeffect "", ""() ; CHECK2: call void @__sanitizer_cov +; CHECK2: call void asm sideeffect "", ""() ; CHECK2-NOT: call void @__sanitizer_cov ; CHECK2: ret void