diff --git a/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 424bd7f7880..459e2b39b32 100644 --- a/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -1156,6 +1156,8 @@ struct MemorySanitizerVisitor : public InstVisitor { Value *getShadow(Value *V) { if (!PropagateShadow) return getCleanShadow(V); if (Instruction *I = dyn_cast(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 { if (isa(V)) return getCleanOrigin(); assert((isa(V) || isa(V)) && "Unexpected value type in getOrigin()"); + if (Instruction *I = dyn_cast(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 { } // ------------------- Visitors. + using InstVisitor::visit; + void visit(Instruction &I) { + if (!I.getMetadata("nosanitize")) + InstVisitor::visit(I); + } /// \brief Instrument LoadInst /// @@ -1342,10 +1353,11 @@ struct MemorySanitizerVisitor : public InstVisitor { /// 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 { 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(&I); diff --git a/test/Instrumentation/MemorySanitizer/call-nosanitize.ll b/test/Instrumentation/MemorySanitizer/call-nosanitize.ll deleted file mode 100644 index b5e6937f9f8..00000000000 --- a/test/Instrumentation/MemorySanitizer/call-nosanitize.ll +++ /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/test/Instrumentation/MemorySanitizer/nosanitize.ll b/test/Instrumentation/MemorySanitizer/nosanitize.ll new file mode 100644 index 00000000000..082a6f580e5 --- /dev/null +++ b/test/Instrumentation/MemorySanitizer/nosanitize.ll @@ -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