diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index dca6bf1adfde8..0663dbd90b415 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -3832,6 +3832,21 @@ struct MemorySanitizerVisitor : public InstVisitor { setOriginForNaryOp(I); } + // _mm_round_ps / _mm_round_ps. + // Similar to maybeHandleSimpleNomemIntrinsic except + // the second argument is guranteed to be a constant integer. + void handleRoundPdPsIntrinsic(IntrinsicInst &I) { + assert(I.getArgOperand(0)->getType() == I.getType()); + unsigned NumArgOperands = I.arg_size(); + assert(NumArgOperands == 2); + assert(isa(I.getArgOperand(1))); + + IRBuilder<> IRB(&I); + ShadowAndOriginCombiner SC(this, IRB); + SC.Add(I.getArgOperand(0)); + SC.Done(&I); + } + // Instrument abs intrinsic. // handleUnknownIntrinsic can't handle it because of the last // is_int_min_poison argument which does not match the result type. @@ -4327,10 +4342,16 @@ struct MemorySanitizerVisitor : public InstVisitor { handlePclmulIntrinsic(I); break; + case Intrinsic::x86_sse41_round_pd: + case Intrinsic::x86_sse41_round_ps: + handleRoundPdPsIntrinsic(I); + break; + case Intrinsic::x86_sse41_round_sd: case Intrinsic::x86_sse41_round_ss: handleUnarySdSsIntrinsic(I); break; + case Intrinsic::x86_sse2_max_sd: case Intrinsic::x86_sse_max_ss: case Intrinsic::x86_sse2_min_sd: diff --git a/llvm/test/Instrumentation/MemorySanitizer/X86/sse41-intrinsics-x86.ll b/llvm/test/Instrumentation/MemorySanitizer/X86/sse41-intrinsics-x86.ll index f5e8452fd0d58..1fcab72d571ea 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/X86/sse41-intrinsics-x86.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/X86/sse41-intrinsics-x86.ll @@ -320,15 +320,8 @@ define <2 x double> @test_x86_sse41_round_pd(<2 x double> %a0) #0 { ; CHECK-LABEL: @test_x86_sse41_round_pd( ; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, 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 [[PROF1]] -; CHECK: 3: -; CHECK-NEXT: call void @__msan_warning_noreturn() -; CHECK-NEXT: unreachable -; CHECK: 4: ; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.x86.sse41.round.pd(<2 x double> [[A0:%.*]], i32 7) -; CHECK-NEXT: store <2 x i64> zeroinitializer, ptr @__msan_retval_tls, align 8 +; CHECK-NEXT: store <2 x i64> [[TMP1]], ptr @__msan_retval_tls, align 8 ; CHECK-NEXT: ret <2 x double> [[RES]] ; %res = call <2 x double> @llvm.x86.sse41.round.pd(<2 x double> %a0, i32 7) ; <<2 x double>> [#uses=1] @@ -341,15 +334,8 @@ define <4 x float> @test_x86_sse41_round_ps(<4 x float> %a0) #0 { ; CHECK-LABEL: @test_x86_sse41_round_ps( ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr @__msan_param_tls, 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 [[PROF1]] -; CHECK: 3: -; CHECK-NEXT: call void @__msan_warning_noreturn() -; CHECK-NEXT: unreachable -; CHECK: 4: ; CHECK-NEXT: [[RES:%.*]] = call <4 x float> @llvm.x86.sse41.round.ps(<4 x float> [[A0:%.*]], i32 7) -; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr @__msan_retval_tls, align 8 +; CHECK-NEXT: store <4 x i32> [[TMP1]], ptr @__msan_retval_tls, align 8 ; CHECK-NEXT: ret <4 x float> [[RES]] ; %res = call <4 x float> @llvm.x86.sse41.round.ps(<4 x float> %a0, i32 7) ; <<4 x float>> [#uses=1] diff --git a/llvm/test/Instrumentation/MemorySanitizer/i386/sse41-intrinsics-i386.ll b/llvm/test/Instrumentation/MemorySanitizer/i386/sse41-intrinsics-i386.ll index a3bda12e395e6..e51c53375d2b5 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/i386/sse41-intrinsics-i386.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/i386/sse41-intrinsics-i386.ll @@ -335,15 +335,8 @@ define <2 x double> @test_x86_sse41_round_pd(<2 x double> %a0) #0 { ; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8 ; CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__msan_va_arg_overflow_size_tls, 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 [[TMP6:%.*]], label [[TMP5:%.*]], !prof [[PROF1]] -; CHECK: 4: -; CHECK-NEXT: call void @__msan_warning_noreturn() -; CHECK-NEXT: unreachable -; CHECK: 5: ; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.x86.sse41.round.pd(<2 x double> [[A0:%.*]], i32 7) -; CHECK-NEXT: store <2 x i64> zeroinitializer, ptr @__msan_retval_tls, align 8 +; CHECK-NEXT: store <2 x i64> [[TMP1]], ptr @__msan_retval_tls, align 8 ; CHECK-NEXT: ret <2 x double> [[RES]] ; %res = call <2 x double> @llvm.x86.sse41.round.pd(<2 x double> %a0, i32 7) ; <<2 x double>> [#uses=1] @@ -357,15 +350,8 @@ define <4 x float> @test_x86_sse41_round_ps(<4 x float> %a0) #0 { ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8 ; CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__msan_va_arg_overflow_size_tls, 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 [[TMP6:%.*]], label [[TMP5:%.*]], !prof [[PROF1]] -; CHECK: 4: -; CHECK-NEXT: call void @__msan_warning_noreturn() -; CHECK-NEXT: unreachable -; CHECK: 5: ; CHECK-NEXT: [[RES:%.*]] = call <4 x float> @llvm.x86.sse41.round.ps(<4 x float> [[A0:%.*]], i32 7) -; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr @__msan_retval_tls, align 8 +; CHECK-NEXT: store <4 x i32> [[TMP1]], ptr @__msan_retval_tls, align 8 ; CHECK-NEXT: ret <4 x float> [[RES]] ; %res = call <4 x float> @llvm.x86.sse41.round.ps(<4 x float> %a0, i32 7) ; <<4 x float>> [#uses=1]