Skip to content

Commit 6c76dd0

Browse files
committed
[msan] Implement support for avx512fp16.mask.{add/sub/mul/div/max/min}.sh.round
This adds a handler, visitGenericScalarHalfwordInst, which works for mask.{add/sub/mul/div/max/min}.sh.round. Updates the tests in llvm#136260
1 parent be7ef6c commit 6c76dd0

File tree

2 files changed

+306
-220
lines changed

2 files changed

+306
-220
lines changed

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4312,6 +4312,65 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
43124312
setOriginForNaryOp(I);
43134313
}
43144314

4315+
// For sh compiler intrinsics:
4316+
// llvm.x86.avx512fp16.mask.{add/sub/mul/div/max/min}.sh.round
4317+
// (<8 x half>, <8 x half>, <8 x half>, i8, i32)
4318+
// A B WriteThru Mask RoundingMode
4319+
//
4320+
// if (Mask[0])
4321+
// DstShadow[0] = AShadow[0] | BShadow[0]
4322+
// else
4323+
// DstShadow[0] = WriteThruShadow[0]
4324+
//
4325+
// DstShadow[1..7] = AShadow[1..7]
4326+
void visitGenericScalarHalfwordInst(IntrinsicInst &I) {
4327+
IRBuilder<> IRB(&I);
4328+
4329+
assert(I.arg_size() == 5);
4330+
Value *A = I.getOperand(0);
4331+
Value *B = I.getOperand(1);
4332+
Value *WriteThrough = I.getOperand(2);
4333+
Value *Mask = I.getOperand(3);
4334+
Value *RoundingMode = I.getOperand(4);
4335+
4336+
// Technically, we could probably just check whether the LSB is initialized
4337+
insertShadowCheck(Mask, &I);
4338+
insertShadowCheck(RoundingMode, &I);
4339+
4340+
assert(isa<FixedVectorType>(A->getType()));
4341+
unsigned NumElements =
4342+
cast<FixedVectorType>(A->getType())->getNumElements();
4343+
assert(NumElements == 8);
4344+
assert(A->getType() == B->getType());
4345+
assert(B->getType() == WriteThrough->getType());
4346+
assert(Mask->getType()->getPrimitiveSizeInBits() == NumElements);
4347+
assert(RoundingMode->getType()->isIntegerTy());
4348+
4349+
Mask = IRB.CreateBitCast(
4350+
Mask, FixedVectorType::get(IRB.getInt1Ty(), NumElements));
4351+
4352+
Value *AShadow = getShadow(A);
4353+
Value *BShadow = getShadow(B);
4354+
Value *ABLowerShadow =
4355+
IRB.CreateOr(IRB.CreateExtractElement(
4356+
AShadow, ConstantInt::get(IRB.getInt32Ty(), 0)),
4357+
IRB.CreateExtractElement(
4358+
BShadow, ConstantInt::get(IRB.getInt32Ty(), 0)));
4359+
Value *WriteThroughShadow = getShadow(WriteThrough);
4360+
Value *WriteThroughLowerShadow = IRB.CreateExtractElement(
4361+
WriteThroughShadow, ConstantInt::get(IRB.getInt32Ty(), 0));
4362+
4363+
Value *DstLowerShadow = IRB.CreateSelect(
4364+
IRB.CreateExtractElement(Mask, ConstantInt::get(IRB.getInt32Ty(), 0)),
4365+
ABLowerShadow, WriteThroughLowerShadow);
4366+
Value *DstShadow = IRB.CreateInsertElement(
4367+
AShadow, DstLowerShadow, ConstantInt::get(IRB.getInt32Ty(), 0),
4368+
"_msprop");
4369+
4370+
setShadow(&I, DstShadow);
4371+
setOriginForNaryOp(I);
4372+
}
4373+
43154374
// Handle Arm NEON vector load intrinsics (vld*).
43164375
//
43174376
// The WithLane instructions (ld[234]lane) are similar to:
@@ -5041,6 +5100,16 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
50415100
break;
50425101
}
50435102

5103+
case Intrinsic::x86_avx512fp16_mask_add_sh_round:
5104+
case Intrinsic::x86_avx512fp16_mask_sub_sh_round:
5105+
case Intrinsic::x86_avx512fp16_mask_mul_sh_round:
5106+
case Intrinsic::x86_avx512fp16_mask_div_sh_round:
5107+
case Intrinsic::x86_avx512fp16_mask_max_sh_round:
5108+
case Intrinsic::x86_avx512fp16_mask_min_sh_round: {
5109+
visitGenericScalarHalfwordInst(I);
5110+
break;
5111+
}
5112+
50445113
case Intrinsic::fshl:
50455114
case Intrinsic::fshr:
50465115
handleFunnelShift(I);

0 commit comments

Comments
 (0)