[msan] Don't sanitize "nosanitize" instructions
authorVitaly Buka <vitalybuka@google.com>
Mon, 20 Nov 2017 23:37:56 +0000 (23:37 +0000)
committerVitaly Buka <vitalybuka@google.com>
Mon, 20 Nov 2017 23:37:56 +0000 (23:37 +0000)
Reviewers: eugenis

Subscribers: hiraditya, llvm-commits

Differential Revision: https://reviews.llvm.org/D40205

llvm-svn: 318708

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
llvm/test/Instrumentation/MemorySanitizer/call-nosanitize.ll [deleted file]
llvm/test/Instrumentation/MemorySanitizer/nosanitize.ll [new file with mode: 0644]

index 424bd7f..459e2b3 100644 (file)
@@ -1156,6 +1156,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
   Value *getShadow(Value *V) {
     if (!PropagateShadow) return getCleanShadow(V);
     if (Instruction *I = dyn_cast<Instruction>(V)) {
+      if (I->getMetadata("nosanitize"))
+        return getCleanShadow(V);
       // For instructions the shadow is already stored in the map.
       Value *Shadow = ShadowMap[V];
       if (!Shadow) {
@@ -1255,6 +1257,10 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
     if (isa<Constant>(V)) return getCleanOrigin();
     assert((isa<Instruction>(V) || isa<Argument>(V)) &&
            "Unexpected value type in getOrigin()");
+    if (Instruction *I = dyn_cast<Instruction>(V)) {
+      if (I->getMetadata("nosanitize"))
+        return getCleanOrigin();
+    }
     Value *Origin = OriginMap[V];
     assert(Origin && "Missing origin");
     return Origin;
@@ -1335,6 +1341,11 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
   }
 
   // ------------------- Visitors.
+  using InstVisitor<MemorySanitizerVisitor>::visit;
+  void visit(Instruction &I) {
+    if (!I.getMetadata("nosanitize"))
+      InstVisitor<MemorySanitizerVisitor>::visit(I);
+  }
 
   /// \brief Instrument LoadInst
   ///
@@ -1342,10 +1353,11 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
   /// Optionally, checks that the load address is fully defined.
   void visitLoadInst(LoadInst &I) {
     assert(I.getType()->isSized() && "Load type must have size");
+    assert(!I.getMetadata("nosanitize"));
     IRBuilder<> IRB(I.getNextNode());
     Type *ShadowTy = getShadowTy(&I);
     Value *Addr = I.getPointerOperand();
-    if (PropagateShadow && !I.getMetadata("nosanitize")) {
+    if (PropagateShadow) {
       Value *ShadowPtr = getShadowPtr(Addr, ShadowTy, IRB);
       setShadow(&I,
                 IRB.CreateAlignedLoad(ShadowPtr, I.getAlignment(), "_msld"));
@@ -2653,7 +2665,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
 
   void visitCallSite(CallSite CS) {
     Instruction &I = *CS.getInstruction();
-    if (I.getMetadata("nosanitize")) return;
+    assert(!I.getMetadata("nosanitize"));
     assert((CS.isCall() || CS.isInvoke()) && "Unknown type of CallSite");
     if (CS.isCall()) {
       CallInst *Call = cast<CallInst>(&I);
diff --git a/llvm/test/Instrumentation/MemorySanitizer/call-nosanitize.ll b/llvm/test/Instrumentation/MemorySanitizer/call-nosanitize.ll
deleted file mode 100644 (file)
index b5e6937..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-; Verify that calls with !nosanitize are not instrumented by MSan.
-; RUN: opt < %s -msan -S | FileCheck %s
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-unknown-linux-gnu"
-
-declare void @bar(i32 %x)
-
-define void @foo() {
-  call void @bar(i32 7), !nosanitize !{}
-  ret void
-}
-
-; CHECK-LABEL: define void @foo
-; CHECK-NOT: store i{{[0-9]+}} 0, {{.*}} @__msan_param_tls
-; CHECK: call void @bar
-; CHECK: ret void
diff --git a/llvm/test/Instrumentation/MemorySanitizer/nosanitize.ll b/llvm/test/Instrumentation/MemorySanitizer/nosanitize.ll
new file mode 100644 (file)
index 0000000..082a6f5
--- /dev/null
@@ -0,0 +1,48 @@
+; Verify that calls with !nosanitize are not instrumented by MSan.
+; RUN: opt < %s -msan -S | FileCheck %s
+; RUN: opt < %s -msan -msan-track-origins=1 -S | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @bar(i32 %x)
+
+define void @foo() {
+  call void @bar(i32 7), !nosanitize !{}
+  ret void
+}
+
+; CHECK-LABEL: define void @foo
+; CHECK-NOT: store {{.*}} @__msan_param_tls
+; CHECK: call void @bar
+; CHECK: ret void
+
+
+@__sancov_gen_ = private global [1 x i8] zeroinitializer, section "__sancov_cntrs", align 1
+define void @sancov() sanitize_memory {
+entry:
+  %0 = load i8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @__sancov_gen_, i64 0, i64 0), !nosanitize !{}
+  %1 = add i8 %0, 1
+  store i8 %1, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @__sancov_gen_, i64 0, i64 0), !nosanitize !{}
+  ret void
+}
+
+; CHECK-LABEL: define void @sancov
+; CHECK-NOT: xor
+; CHECK-NOT: 87960930222080
+; CHECK: ret void
+
+
+define void @load_store() sanitize_memory {
+entry:
+  %x = alloca i32, align 4, !nosanitize !{}
+  store i32 4, i32* %x, align 4, !nosanitize !{}
+  %0 = load i32, i32* %x, align 4, !nosanitize !{}
+  %add = add nsw i32 %0, %0
+  store i32 %add, i32* %x, align 4, !nosanitize !{}
+  ret void
+}
+
+; CHECK-LABEL: define void @load_store
+; CHECK-NOT: xor
+; CHECK-NOT: 87960930222080
+; CHECK: ret void