[llvm] r232873 - [sanitizer] experimental tracing for cmp instructions

Kostya Serebryany kcc at google.com
Fri Mar 20 18:29:36 PDT 2015


Author: kcc
Date: Fri Mar 20 20:29:36 2015
New Revision: 232873

URL: http://llvm.org/viewvc/llvm-project?rev=232873&view=rev
Log:
[sanitizer] experimental tracing for cmp instructions

Added:
    llvm/trunk/test/Instrumentation/SanitizerCoverage/cmp-tracing.ll
Modified:
    llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp

Modified: llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp?rev=232873&r1=232872&r2=232873&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp Fri Mar 20 20:29:36 2015
@@ -59,6 +59,7 @@ static const char *const kSanCovWithChec
 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";
+static const char *const kSanCovTraceCmp = "__sanitizer_cov_trace_cmp";
 static const char *const kSanCovModuleCtorName = "sancov.module_ctor";
 static const uint64_t    kSanCtorAndDtorPriority = 2;
 
@@ -80,6 +81,12 @@ static cl::opt<bool>
                                    "callbacks at every basic block"),
                           cl::Hidden, cl::init(false));
 
+static cl::opt<bool>
+    ClExperimentalCMPTracing("sanitizer-coverage-experimental-trace-compares",
+                             cl::desc("Experimental tracing of CMP and similar "
+                                      "instructions"),
+                             cl::Hidden, cl::init(false));
+
 // Experimental 8-bit counters used as an additional search heuristic during
 // coverage-guided fuzzing.
 // The counters are not thread-friendly:
@@ -107,8 +114,8 @@ class SanitizerCoverageModule : public M
  private:
   void InjectCoverageForIndirectCalls(Function &F,
                                       ArrayRef<Instruction *> IndirCalls);
-  bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks,
-                      ArrayRef<Instruction *> IndirCalls);
+  void InjectTraceForCmp(Function &F, ArrayRef<Instruction *> CmpTraceTargets);
+  bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks);
   void SetNoSanitizeMetada(Instruction *I);
   void InjectCoverageAtBlock(Function &F, BasicBlock &BB, bool UseCalls);
   unsigned NumberOfInstrumentedBlocks() {
@@ -119,9 +126,11 @@ class SanitizerCoverageModule : public M
   Function *SanCovIndirCallFunction;
   Function *SanCovModuleInit;
   Function *SanCovTraceEnter, *SanCovTraceBB;
+  Function *SanCovTraceCmpFunction;
   InlineAsm *EmptyAsm;
-  Type *IntptrTy;
+  Type *IntptrTy, *Int64Ty;
   LLVMContext *C;
+  const DataLayout *DL;
 
   GlobalVariable *GuardArray;
   GlobalVariable *EightBitCounterArray;
@@ -144,12 +153,13 @@ static Function *checkInterfaceFunction(
 bool SanitizerCoverageModule::runOnModule(Module &M) {
   if (!CoverageLevel) return false;
   C = &(M.getContext());
-  auto &DL = M.getDataLayout();
-  IntptrTy = Type::getIntNTy(*C, DL.getPointerSizeInBits());
+  DL = &M.getDataLayout();
+  IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
   Type *VoidTy = Type::getVoidTy(*C);
   IRBuilder<> IRB(*C);
   Type *Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty());
   Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
+  Int64Ty = IRB.getInt64Ty();
 
   Function *CtorFunc =
       Function::Create(FunctionType::get(VoidTy, false),
@@ -163,6 +173,9 @@ bool SanitizerCoverageModule::runOnModul
       M.getOrInsertFunction(kSanCovWithCheckName, VoidTy, Int32PtrTy, nullptr));
   SanCovIndirCallFunction = checkInterfaceFunction(M.getOrInsertFunction(
       kSanCovIndirCallName, VoidTy, IntptrTy, IntptrTy, nullptr));
+  SanCovTraceCmpFunction = checkInterfaceFunction(M.getOrInsertFunction(
+      kSanCovTraceCmp, VoidTy, Int64Ty, Int64Ty, Int64Ty, nullptr));
+
   SanCovModuleInit = checkInterfaceFunction(M.getOrInsertFunction(
       kSanCovModuleInitName, Type::getVoidTy(*C), Int32PtrTy, IntptrTy,
       Int8PtrTy, Int8PtrTy, nullptr));
@@ -252,23 +265,28 @@ bool SanitizerCoverageModule::runOnFunct
     SplitAllCriticalEdges(F);
   SmallVector<Instruction*, 8> IndirCalls;
   SmallVector<BasicBlock*, 16> AllBlocks;
+  SmallVector<Instruction*, 8> CmpTraceTargets;
   for (auto &BB : F) {
     AllBlocks.push_back(&BB);
-    if (CoverageLevel >= 4)
-      for (auto &Inst : BB) {
+    for (auto &Inst : BB) {
+      if (CoverageLevel >= 4) {
         CallSite CS(&Inst);
         if (CS && !CS.getCalledFunction())
           IndirCalls.push_back(&Inst);
       }
+      if (ClExperimentalCMPTracing)
+        if (isa<ICmpInst>(&Inst))
+          CmpTraceTargets.push_back(&Inst);
+    }
   }
-  InjectCoverage(F, AllBlocks, IndirCalls);
+  InjectCoverage(F, AllBlocks);
+  InjectCoverageForIndirectCalls(F, IndirCalls);
+  InjectTraceForCmp(F, CmpTraceTargets);
   return true;
 }
 
-bool
-SanitizerCoverageModule::InjectCoverage(Function &F,
-                                        ArrayRef<BasicBlock *> AllBlocks,
-                                        ArrayRef<Instruction *> IndirCalls) {
+bool SanitizerCoverageModule::InjectCoverage(Function &F,
+                                             ArrayRef<BasicBlock *> AllBlocks) {
   if (!CoverageLevel) return false;
 
   if (CoverageLevel == 1) {
@@ -278,7 +296,6 @@ SanitizerCoverageModule::InjectCoverage(
       InjectCoverageAtBlock(F, *BB,
                             ClCoverageBlockThreshold < AllBlocks.size());
   }
-  InjectCoverageForIndirectCalls(F, IndirCalls);
   return true;
 }
 
@@ -310,6 +327,26 @@ void SanitizerCoverageModule::InjectCove
   }
 }
 
+void SanitizerCoverageModule::InjectTraceForCmp(
+    Function &F, ArrayRef<Instruction *> CmpTraceTargets) {
+  if (!ClExperimentalCMPTracing) return;
+  for (auto I : CmpTraceTargets) {
+    if (ICmpInst *ICMP = dyn_cast<ICmpInst>(I)) {
+      IRBuilder<> IRB(ICMP);
+      Value *A0 = ICMP->getOperand(0);
+      Value *A1 = ICMP->getOperand(1);
+      if (!A0->getType()->isIntegerTy()) continue;
+      uint64_t TypeSize = DL->getTypeStoreSizeInBits(A0->getType());
+      // __sanitizer_cov_indir_call((type_size << 32) | predicate, A0, A1);
+      IRB.CreateCall3(
+          SanCovTraceCmpFunction,
+          ConstantInt::get(Int64Ty, (TypeSize << 32) | ICMP->getPredicate()),
+          IRB.CreateIntCast(A0, Int64Ty, true),
+          IRB.CreateIntCast(A1, Int64Ty, true));
+    }
+  }
+}
+
 void SanitizerCoverageModule::SetNoSanitizeMetada(Instruction *I) {
   I->setMetadata(
       I->getParent()->getParent()->getParent()->getMDKindID("nosanitize"),

Added: llvm/trunk/test/Instrumentation/SanitizerCoverage/cmp-tracing.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/SanitizerCoverage/cmp-tracing.ll?rev=232873&view=auto
==============================================================================
--- llvm/trunk/test/Instrumentation/SanitizerCoverage/cmp-tracing.ll (added)
+++ llvm/trunk/test/Instrumentation/SanitizerCoverage/cmp-tracing.ll Fri Mar 20 20:29:36 2015
@@ -0,0 +1,13 @@
+; Test -sanitizer-coverage-experimental-trace-compares=1
+; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-experimental-trace-compares=1  -S | FileCheck %s --check-prefix=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"
+define i32 @foo(i32 %a, i32 %b) #0 {
+entry:
+  %cmp = icmp slt i32 %a, %b
+; CHECK: call void @__sanitizer_cov_trace_cmp
+; CHECK-NEXT: icmp slt i32 %a, %b
+  %conv = zext i1 %cmp to i32
+  ret i32 %conv
+}





More information about the llvm-commits mailing list