[llvm] r310600 - [sanitizer-coverage] Change cmp instrumentation to distinguish const operands
Alexander Potapenko via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 10 08:00:14 PDT 2017
Author: glider
Date: Thu Aug 10 08:00:13 2017
New Revision: 310600
URL: http://llvm.org/viewvc/llvm-project?rev=310600&view=rev
Log:
[sanitizer-coverage] Change cmp instrumentation to distinguish const operands
This implementation of SanitizerCoverage instrumentation inserts different
callbacks depending on constantness of operands:
1. If both operands are non-const, then a usual
__sanitizer_cov_trace_cmp[1248] call is inserted.
2. If exactly one operand is const, then a
__sanitizer_cov_trace_const_cmp[1248] call is inserted. The first
argument of the call is always the constant one.
3. If both operands are const, then no callback is inserted.
This separation comes useful in fuzzing when tasks like "find one operand
of the comparison in input arguments and replace it with the other one"
have to be done. The new instrumentation allows us to not waste time on
searching the constant operands in the input.
Patch by Victor Chibotaru.
Added:
llvm/trunk/test/Instrumentation/SanitizerCoverage/const-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=310600&r1=310599&r2=310600&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp Thu Aug 10 08:00:13 2017
@@ -46,6 +46,14 @@ static const char *const SanCovTraceCmp1
static const char *const SanCovTraceCmp2 = "__sanitizer_cov_trace_cmp2";
static const char *const SanCovTraceCmp4 = "__sanitizer_cov_trace_cmp4";
static const char *const SanCovTraceCmp8 = "__sanitizer_cov_trace_cmp8";
+static const char *const SanCovTraceConstCmp1 =
+ "__sanitizer_cov_trace_const_cmp1";
+static const char *const SanCovTraceConstCmp2 =
+ "__sanitizer_cov_trace_const_cmp2";
+static const char *const SanCovTraceConstCmp4 =
+ "__sanitizer_cov_trace_const_cmp4";
+static const char *const SanCovTraceConstCmp8 =
+ "__sanitizer_cov_trace_const_cmp8";
static const char *const SanCovTraceDiv4 = "__sanitizer_cov_trace_div4";
static const char *const SanCovTraceDiv8 = "__sanitizer_cov_trace_div8";
static const char *const SanCovTraceGep = "__sanitizer_cov_trace_gep";
@@ -204,12 +212,13 @@ private:
Function *SanCovTracePCIndir;
Function *SanCovTracePC, *SanCovTracePCGuard;
Function *SanCovTraceCmpFunction[4];
+ Function *SanCovTraceConstCmpFunction[4];
Function *SanCovTraceDivFunction[2];
Function *SanCovTraceGepFunction;
Function *SanCovTraceSwitchFunction;
InlineAsm *EmptyAsm;
Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy,
- *Int8Ty, *Int8PtrTy;
+ *Int16Ty, *Int8Ty, *Int8PtrTy;
Module *CurModule;
Triple TargetTriple;
LLVMContext *C;
@@ -281,6 +290,7 @@ bool SanitizerCoverageModule::runOnModul
Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty());
Int64Ty = IRB.getInt64Ty();
Int32Ty = IRB.getInt32Ty();
+ Int16Ty = IRB.getInt16Ty();
Int8Ty = IRB.getInt8Ty();
SanCovTracePCIndir = checkSanitizerInterfaceFunction(
@@ -298,6 +308,19 @@ bool SanitizerCoverageModule::runOnModul
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
SanCovTraceCmp8, VoidTy, Int64Ty, Int64Ty));
+ SanCovTraceConstCmpFunction[0] =
+ checkSanitizerInterfaceFunction(M.getOrInsertFunction(
+ SanCovTraceConstCmp1, VoidTy, Int8Ty, Int8Ty));
+ SanCovTraceConstCmpFunction[1] =
+ checkSanitizerInterfaceFunction(M.getOrInsertFunction(
+ SanCovTraceConstCmp2, VoidTy, Int16Ty, Int16Ty));
+ SanCovTraceConstCmpFunction[2] =
+ checkSanitizerInterfaceFunction(M.getOrInsertFunction(
+ SanCovTraceConstCmp4, VoidTy, Int32Ty, Int32Ty));
+ SanCovTraceConstCmpFunction[3] =
+ checkSanitizerInterfaceFunction(M.getOrInsertFunction(
+ SanCovTraceConstCmp8, VoidTy, Int64Ty, Int64Ty));
+
SanCovTraceDivFunction[0] =
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
SanCovTraceDiv4, VoidTy, IRB.getInt32Ty()));
@@ -316,6 +339,8 @@ bool SanitizerCoverageModule::runOnModul
for (int i = 0; i < 3; i++) {
SanCovTraceCmpFunction[i]->addParamAttr(0, Attribute::ZExt);
SanCovTraceCmpFunction[i]->addParamAttr(1, Attribute::ZExt);
+ SanCovTraceConstCmpFunction[i]->addParamAttr(0, Attribute::ZExt);
+ SanCovTraceConstCmpFunction[i]->addParamAttr(1, Attribute::ZExt);
}
SanCovTraceDivFunction[0]->addParamAttr(0, Attribute::ZExt);
}
@@ -644,10 +669,21 @@ void SanitizerCoverageModule::InjectTrac
TypeSize == 64 ? 3 : -1;
if (CallbackIdx < 0) continue;
// __sanitizer_cov_trace_cmp((type_size << 32) | predicate, A0, A1);
+ auto CallbackFunc = SanCovTraceCmpFunction[CallbackIdx];
+ bool FirstIsConst = isa<ConstantInt>(A0);
+ bool SecondIsConst = isa<ConstantInt>(A1);
+ // If both are const, then we don't need such a comparison.
+ if (FirstIsConst && SecondIsConst) continue;
+ // If only one is const, then make it the first callback argument.
+ if (FirstIsConst || SecondIsConst) {
+ CallbackFunc = SanCovTraceConstCmpFunction[CallbackIdx];
+ if (SecondIsConst)
+ std::swap(A0, A1);
+ }
+
auto Ty = Type::getIntNTy(*C, TypeSize);
- IRB.CreateCall(
- SanCovTraceCmpFunction[CallbackIdx],
- {IRB.CreateIntCast(A0, Ty, true), IRB.CreateIntCast(A1, Ty, true)});
+ IRB.CreateCall(CallbackFunc, {IRB.CreateIntCast(A0, Ty, true),
+ IRB.CreateIntCast(A1, Ty, true)});
}
}
}
Added: llvm/trunk/test/Instrumentation/SanitizerCoverage/const-cmp-tracing.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/SanitizerCoverage/const-cmp-tracing.ll?rev=310600&view=auto
==============================================================================
--- llvm/trunk/test/Instrumentation/SanitizerCoverage/const-cmp-tracing.ll (added)
+++ llvm/trunk/test/Instrumentation/SanitizerCoverage/const-cmp-tracing.ll Thu Aug 10 08:00:13 2017
@@ -0,0 +1,64 @@
+; Test -sanitizer-coverage-trace-compares=1
+; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -S | FileCheck %s
+
+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:
+
+; compare (non-const, non-const)
+ %cmp = icmp slt i32 %a, %b
+; CHECK: call void @__sanitizer_cov_trace_cmp4
+; CHECK-NEXT: icmp slt i32 %a, %b
+
+; compare (const, non-const)
+ icmp slt i32 %a, 1
+; CHECK: call void @__sanitizer_cov_trace_const_cmp4(i32 1, i32 %a)
+; CHECK-NEXT: icmp slt i32 %a, 1
+
+; compare (non-const, const)
+ icmp slt i32 1, %a
+; CHECK: call void @__sanitizer_cov_trace_const_cmp4(i32 1, i32 %a)
+; CHECK-NEXT: icmp slt i32 1, %a
+
+; compare (const, const) - should not be instrumented
+ icmp slt i32 1, 0
+; CHECK-NOT: call void @__sanitizer_cov_trace
+; CHECK icmp slt i32 1, 0
+
+; compare variables of byte size
+ %x = trunc i32 %a to i8
+
+ icmp slt i8 %x, 1
+; CHECK: call void @__sanitizer_cov_trace_const_cmp1(i8 1, i8 %x)
+; CHECK-NEXT: icmp slt i8 %x, 1
+
+ icmp slt i8 1, %x
+; CHECK: call void @__sanitizer_cov_trace_const_cmp1(i8 1, i8 %x)
+; CHECK-NEXT: icmp slt i8 1, %x
+
+; compare variables of word size
+ %y = trunc i32 %a to i16
+
+ icmp slt i16 %y, 1
+; CHECK: call void @__sanitizer_cov_trace_const_cmp2(i16 1, i16 %y)
+; CHECK-NEXT: icmp slt i16 %y, 1
+
+ icmp slt i16 1, %y
+; CHECK: call void @__sanitizer_cov_trace_const_cmp2(i16 1, i16 %y)
+; CHECK-NEXT: icmp slt i16 1, %y
+
+; compare variables of qword size
+ %z = zext i32 %a to i64
+
+ icmp slt i64 %z, 1
+; CHECK: call void @__sanitizer_cov_trace_const_cmp8(i64 1, i64 %z)
+; CHECK-NEXT: icmp slt i64 %z, 1
+
+ icmp slt i64 1, %z
+; CHECK: call void @__sanitizer_cov_trace_const_cmp8(i64 1, i64 %z)
+; CHECK-NEXT: icmp slt i64 1, %z
+
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+}
More information about the llvm-commits
mailing list