@@ -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