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 @@ -3509,6 +3509,20 @@ setOriginForNaryOp(I); } + void handleMovmskIntrinsic(IntrinsicInst &I) { + IRBuilder<> IRB(&I); + + // Do the same operation for the shadow as the first argument. + Value *ShadowIn = + IRB.CreateBitCast(getShadow(&I, 0), I.getArgOperand(0)->getType()); + IntrinsicInst *ShadowInst = cast(IRB.Insert(I.clone())); + ShadowInst->setArgOperand(0, ShadowIn); + Value *Shadow = IRB.CreateBitCast(ShadowInst, getShadowTy(&I)); + + setShadow(&I, Shadow); + setOriginForNaryOp(I); + } + void handleVtestIntrinsic(IntrinsicInst &I) { IRBuilder<> IRB(&I); Value* Shadow0 = getShadow(&I, 0); @@ -3854,6 +3868,13 @@ handleVtestIntrinsic(I); break; + case Intrinsic::x86_avx_movmsk_pd_256: + case Intrinsic::x86_avx_movmsk_ps_256: + case Intrinsic::x86_sse_movmsk_ps: + case Intrinsic::x86_sse2_movmsk_pd: + handleMovmskIntrinsic(I); + break; + case Intrinsic::fshl: case Intrinsic::fshr: handleFunnelShift(I); diff --git a/llvm/test/Instrumentation/MemorySanitizer/avx-intrinsics-x86.ll b/llvm/test/Instrumentation/MemorySanitizer/avx-intrinsics-x86.ll --- a/llvm/test/Instrumentation/MemorySanitizer/avx-intrinsics-x86.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/avx-intrinsics-x86.ll @@ -769,15 +769,10 @@ ; CHECK-LABEL: @test_x86_avx_movmsk_pd_256( ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i64>, <4 x i64>* bitcast ([100 x i64]* @__msan_param_tls to <4 x i64>*), align 8 ; CHECK-NEXT: call void @llvm.donothing() -; CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i64> [[TMP1]] to i256 -; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i256 [[TMP2]], 0 -; CHECK-NEXT: br i1 [[_MSCMP]], label [[TMP3:%.*]], label [[TMP4:%.*]], !prof [[PROF0]] -; CHECK: 3: -; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR8]] -; CHECK-NEXT: unreachable -; CHECK: 4: +; CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i64> [[TMP1]] to <4 x double> +; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.x86.avx.movmsk.pd.256(<4 x double> [[TMP2]]) ; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.avx.movmsk.pd.256(<4 x double> [[A0:%.*]]) -; CHECK-NEXT: store i32 0, i32* bitcast ([100 x i64]* @__msan_retval_tls to i32*), align 8 +; CHECK-NEXT: store i32 [[TMP3]], i32* bitcast ([100 x i64]* @__msan_retval_tls to i32*), align 8 ; CHECK-NEXT: ret i32 [[RES]] ; %res = call i32 @llvm.x86.avx.movmsk.pd.256(<4 x double> %a0) ; [#uses=1] @@ -790,15 +785,10 @@ ; CHECK-LABEL: @test_x86_avx_movmsk_ps_256( ; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i32>, <8 x i32>* bitcast ([100 x i64]* @__msan_param_tls to <8 x i32>*), align 8 ; CHECK-NEXT: call void @llvm.donothing() -; CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i32> [[TMP1]] to i256 -; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i256 [[TMP2]], 0 -; CHECK-NEXT: br i1 [[_MSCMP]], label [[TMP3:%.*]], label [[TMP4:%.*]], !prof [[PROF0]] -; CHECK: 3: -; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR8]] -; CHECK-NEXT: unreachable -; CHECK: 4: +; CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i32> [[TMP1]] to <8 x float> +; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> [[TMP2]]) ; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> [[A0:%.*]]) -; CHECK-NEXT: store i32 0, i32* bitcast ([100 x i64]* @__msan_retval_tls to i32*), align 8 +; CHECK-NEXT: store i32 [[TMP3]], i32* bitcast ([100 x i64]* @__msan_retval_tls to i32*), align 8 ; CHECK-NEXT: ret i32 [[RES]] ; %res = call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> %a0) ; [#uses=1] diff --git a/llvm/test/Instrumentation/MemorySanitizer/sse-intrinsics-x86.ll b/llvm/test/Instrumentation/MemorySanitizer/sse-intrinsics-x86.ll --- a/llvm/test/Instrumentation/MemorySanitizer/sse-intrinsics-x86.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/sse-intrinsics-x86.ll @@ -294,15 +294,10 @@ ; CHECK-LABEL: @test_x86_sse_movmsk_ps( ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* bitcast ([100 x i64]* @__msan_param_tls to <4 x i32>*), align 8 ; CHECK-NEXT: call void @llvm.donothing() -; CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 -; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i128 [[TMP2]], 0 -; CHECK-NEXT: br i1 [[_MSCMP]], label [[TMP3:%.*]], label [[TMP4:%.*]], !prof [[PROF0]] -; CHECK: 3: -; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR5]] -; CHECK-NEXT: unreachable -; CHECK: 4: +; CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP1]] to <4 x float> +; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.x86.sse.movmsk.ps(<4 x float> [[TMP2]]) ; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse.movmsk.ps(<4 x float> [[A0:%.*]]) -; CHECK-NEXT: store i32 0, i32* bitcast ([100 x i64]* @__msan_retval_tls to i32*), align 8 +; CHECK-NEXT: store i32 [[TMP3]], i32* bitcast ([100 x i64]* @__msan_retval_tls to i32*), align 8 ; CHECK-NEXT: ret i32 [[RES]] ; %res = call i32 @llvm.x86.sse.movmsk.ps(<4 x float> %a0) ; [#uses=1] diff --git a/llvm/test/Instrumentation/MemorySanitizer/sse2-intrinsics-x86.ll b/llvm/test/Instrumentation/MemorySanitizer/sse2-intrinsics-x86.ll --- a/llvm/test/Instrumentation/MemorySanitizer/sse2-intrinsics-x86.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/sse2-intrinsics-x86.ll @@ -637,15 +637,10 @@ ; CHECK-LABEL: @test_x86_sse2_movmsk_pd( ; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* bitcast ([100 x i64]* @__msan_param_tls to <2 x i64>*), align 8 ; CHECK-NEXT: call void @llvm.donothing() -; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 -; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i128 [[TMP2]], 0 -; CHECK-NEXT: br i1 [[_MSCMP]], label [[TMP3:%.*]], label [[TMP4:%.*]], !prof [[PROF0]] -; CHECK: 3: -; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR6]] -; CHECK-NEXT: unreachable -; CHECK: 4: +; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to <2 x double> +; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.x86.sse2.movmsk.pd(<2 x double> [[TMP2]]) ; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.movmsk.pd(<2 x double> [[A0:%.*]]) -; CHECK-NEXT: store i32 0, i32* bitcast ([100 x i64]* @__msan_retval_tls to i32*), align 8 +; CHECK-NEXT: store i32 [[TMP3]], i32* bitcast ([100 x i64]* @__msan_retval_tls to i32*), align 8 ; CHECK-NEXT: ret i32 [[RES]] ; %res = call i32 @llvm.x86.sse2.movmsk.pd(<2 x double> %a0) ; [#uses=1]