diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -1672,9 +1672,8 @@ /// This function either returns the value set earlier with setShadow, /// or extracts if from ParamTLS (for function arguments). Value *getShadow(Value *V) { - if (!PropagateShadow) return getCleanShadow(V); if (Instruction *I = dyn_cast(V)) { - if (I->getMetadata("nosanitize")) + if (!PropagateShadow || I->getMetadata("nosanitize")) return getCleanShadow(V); // For instructions the shadow is already stored in the map. Value *Shadow = ShadowMap[V]; @@ -1686,7 +1685,7 @@ return Shadow; } if (UndefValue *U = dyn_cast(V)) { - Value *AllOnes = PoisonUndef ? getPoisonedShadow(V) : getCleanShadow(V); + Value *AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(V) : getCleanShadow(V); LLVM_DEBUG(dbgs() << "Undef: " << *U << " ==> " << *AllOnes << "\n"); (void)U; return AllOnes; @@ -1723,7 +1722,7 @@ /*isStore*/ true) .first; // TODO(glider): need to copy origins. - if (Overflow) { + if (!PropagateShadow || Overflow) { // ParamTLS overflow. EntryIRB.CreateMemSet( CpShadowPtr, Constant::getNullValue(EntryIRB.getInt8Ty()), @@ -1738,7 +1737,7 @@ } } - if (Overflow || FArg.hasByValAttr() || + if (!PropagateShadow || Overflow || FArg.hasByValAttr() || (MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) { *ShadowPtr = getCleanShadow(V); setOrigin(A, getCleanOrigin()); diff --git a/llvm/test/Instrumentation/MemorySanitizer/byval.ll b/llvm/test/Instrumentation/MemorySanitizer/byval.ll --- a/llvm/test/Instrumentation/MemorySanitizer/byval.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/byval.ll @@ -25,6 +25,7 @@ define i16 @ByValArgumentNoSanitize(i32 %unused, i16* byval(i16) %p) { ; CHECK-LABEL: @ByValArgumentNoSanitize( ; CHECK-NEXT: entry: +; CHECK: call void @llvm.memset.p0i8.i64(i8* align 2 {{.*}}, i8 0, i64 2, i1 false) ; CHECK: %x = load i16, i16* %p ; CHECK: store i16 0, i16* bitcast ([100 x i64]* @__msan_retval_tls to i16*), align 8 ; CHECK-NEXT: store i32 0, i32* @__msan_retval_origin_tls, align 4 @@ -49,10 +50,10 @@ ret void } -; FIXME: Shadow of byval pointee is not set. define void @ByValForwardNoSanitize(i32 %unused, i16* byval(i16) %p) { ; CHECK-LABEL: @ByValForwardNoSanitize( ; CHECK-NEXT: entry: +; CHECK: call void @llvm.memset.p0i8.i64(i8* align 2 {{.*}}, i8 0, i64 2, i1 false) ; CHECK: store i64 0, i64* getelementptr inbounds ([100 x i64], [100 x i64]* @__msan_param_tls, i32 0, i32 0), align 8 ; CHECK-NEXT: call void @Fn(i16* ; CHECK-NEXT: ret void