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 @@ -3726,10 +3726,14 @@ getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), Alignment, /*isStore*/ false) .first; - - Store = IRB.CreateMemCpy(ArgShadowBase, Alignment, AShadowPtr, - Alignment, Size); - // TODO(glider): need to copy origins. + if (!PropagateShadow) { + Store = IRB.CreateMemSet(ArgShadowBase, + Constant::getNullValue(IRB.getInt8Ty()), + Size, Alignment); + } else { + Store = IRB.CreateMemCpy(ArgShadowBase, Alignment, AShadowPtr, + Alignment, Size); + } } else { // Any other parameters mean we need bit-grained tracking of uninit // data 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 @@ -79,12 +79,11 @@ ret void } -; FIXME: Shadow for byval should be reset not copied before the call. define void @ByValForwardByValNoSanitize(i32, i128* byval(i128) %p) { ; CHECK-LABEL: @ByValForwardByValNoSanitize( ; CHECK-NEXT: entry: ; CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 {{.*}}, i8 0, i64 16, i1 false) -; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast ([100 x i64]* @__msan_param_tls to i8*), i8* {{.*}}, i64 16, i1 false) +; CHECK: call void @llvm.memset.p0i8.i64(i8* bitcast ([100 x i64]* @__msan_param_tls to i8*), i8 0, i64 16, i1 false) ; CHECK: store i32 0, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__msan_param_origin_tls, i32 0, i32 0) ; CHECK-NEXT: call void @FnByVal( ; CHECK-NEXT: ret void