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 @@ -3202,27 +3202,39 @@ SOC.Done(&I); } - // Instrument _mm_*_sd intrinsics - void handleUnarySdIntrinsic(IntrinsicInst &I) { + // Instrument _mm_*_sd|ss intrinsics + void handleUnarySdSsIntrinsic(IntrinsicInst &I) { IRBuilder<> IRB(&I); + unsigned Width = + cast(I.getArgOperand(0)->getType())->getNumElements(); Value *First = getShadow(&I, 0); Value *Second = getShadow(&I, 1); - // High word of first operand, low word of second - Value *Shadow = - IRB.CreateShuffleVector(First, Second, llvm::makeArrayRef({2, 1})); + // First element of second operand, remaining elements of first operand + SmallVector Mask; + Mask.push_back(Width); + for (int i = 1; i < Width; i++) { + Mask.push_back(i); + } + Value *Shadow = IRB.CreateShuffleVector(First, Second, Mask); setShadow(&I, Shadow); setOriginForNaryOp(I); } - void handleBinarySdIntrinsic(IntrinsicInst &I) { + void handleBinarySdSsIntrinsic(IntrinsicInst &I) { IRBuilder<> IRB(&I); + unsigned Width = + cast(I.getArgOperand(0)->getType())->getNumElements(); Value *First = getShadow(&I, 0); Value *Second = getShadow(&I, 1); Value *OrShadow = IRB.CreateOr(First, Second); - // High word of first operand, low word of both OR'd together - Value *Shadow = IRB.CreateShuffleVector(First, OrShadow, - llvm::makeArrayRef({2, 1})); + // First element of both OR'd together, remaining elements of first operand + SmallVector Mask; + Mask.push_back(Width); + for (int i = 1; i < Width; i++) { + Mask.push_back(i); + } + Value *Shadow = IRB.CreateShuffleVector(First, OrShadow, Mask); setShadow(&I, Shadow); setOriginForNaryOp(I); @@ -3497,11 +3509,16 @@ break; case Intrinsic::x86_sse41_round_sd: - handleUnarySdIntrinsic(I); + case Intrinsic::x86_sse41_round_ss: + case Intrinsic::x86_sse_rcp_ss: + case Intrinsic::x86_sse_rsqrt_ss: + handleUnarySdSsIntrinsic(I); break; case Intrinsic::x86_sse2_max_sd: + case Intrinsic::x86_sse_max_ss: case Intrinsic::x86_sse2_min_sd: - handleBinarySdIntrinsic(I); + case Intrinsic::x86_sse_min_ss: + handleBinarySdSsIntrinsic(I); break; case Intrinsic::fshl: