Skip to content

Commit eae84b4

Browse files
committed
[MSAN] Handle x86 {round,min,max}sd intrinsics
These need special handling over the simple vector intrinsics as they behave more like a shuffle operation: taking the top half of the vector from one input, and the bottom half separately. Previously, these were being handled as though all bits of all operands were combined. Differential Revision: https://reviews.llvm.org/D82398
1 parent 9aa9855 commit eae84b4

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3046,6 +3046,32 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
30463046
SOC.Done(&I);
30473047
}
30483048

3049+
// Instrument _mm_*_sd intrinsics
3050+
void handleUnarySdIntrinsic(IntrinsicInst &I) {
3051+
IRBuilder<> IRB(&I);
3052+
Value *First = getShadow(&I, 0);
3053+
Value *Second = getShadow(&I, 1);
3054+
// High word of first operand, low word of second
3055+
Value *Shadow =
3056+
IRB.CreateShuffleVector(First, Second, llvm::makeArrayRef<int>({2, 1}));
3057+
3058+
setShadow(&I, Shadow);
3059+
setOriginForNaryOp(I);
3060+
}
3061+
3062+
void handleBinarySdIntrinsic(IntrinsicInst &I) {
3063+
IRBuilder<> IRB(&I);
3064+
Value *First = getShadow(&I, 0);
3065+
Value *Second = getShadow(&I, 1);
3066+
Value *OrShadow = IRB.CreateOr(First, Second);
3067+
// High word of first operand, low word of both OR'd together
3068+
Value *Shadow = IRB.CreateShuffleVector(First, OrShadow,
3069+
llvm::makeArrayRef<int>({2, 1}));
3070+
3071+
setShadow(&I, Shadow);
3072+
setOriginForNaryOp(I);
3073+
}
3074+
30493075
void visitIntrinsicInst(IntrinsicInst &I) {
30503076
switch (I.getIntrinsicID()) {
30513077
case Intrinsic::lifetime_start:
@@ -3285,6 +3311,14 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
32853311
handlePclmulIntrinsic(I);
32863312
break;
32873313

3314+
case Intrinsic::x86_sse41_round_sd:
3315+
handleUnarySdIntrinsic(I);
3316+
break;
3317+
case Intrinsic::x86_sse2_max_sd:
3318+
case Intrinsic::x86_sse2_min_sd:
3319+
handleBinarySdIntrinsic(I);
3320+
break;
3321+
32883322
case Intrinsic::is_constant:
32893323
// The result of llvm.is.constant() is always defined.
32903324
setShadow(&I, getCleanShadow(&I));

0 commit comments

Comments
 (0)