@@ -4173,7 +4173,15 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
41734173
41744174 // Instrument AVX permutation intrinsic.
41754175 // We apply the same permutation (argument index 1) to the shadow.
4176- void handleAVXVpermilvar (IntrinsicInst &I) {
4176+ void handleAVXPermutation (IntrinsicInst &I) {
4177+ assert (I.arg_size () == 2 );
4178+ assert (isa<FixedVectorType>(I.getArgOperand (0 )->getType ()));
4179+ assert (isa<FixedVectorType>(I.getArgOperand (1 )->getType ()));
4180+ [[maybe_unused]] auto ArgVectorSize =
4181+ cast<FixedVectorType>(I.getArgOperand (0 )->getType ())->getNumElements ();
4182+ assert (cast<FixedVectorType>(I.getArgOperand (1 )->getType ())
4183+ ->getNumElements () == ArgVectorSize);
4184+ assert (I.getType () == I.getArgOperand (0 )->getType ());
41774185 IRBuilder<> IRB (&I);
41784186 Value *Shadow = getShadow (&I, 0 );
41794187 insertShadowCheck (I.getArgOperand (1 ), &I);
@@ -4187,6 +4195,38 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
41874195 setShadow (&I, IRB.CreateBitCast (CI, getShadowTy (&I)));
41884196 setOriginForNaryOp (I);
41894197 }
4198+ // Instrument AVX permutation intrinsic.
4199+ // We apply the same permutation (argument index 1) to the shadows.
4200+ void handleAVXVpermil2var (IntrinsicInst &I) {
4201+ assert (I.arg_size () == 3 );
4202+ assert (isa<FixedVectorType>(I.getArgOperand (0 )->getType ()));
4203+ assert (isa<FixedVectorType>(I.getArgOperand (1 )->getType ()));
4204+ assert (isa<FixedVectorType>(I.getArgOperand (2 )->getType ()));
4205+ [[maybe_unused]] auto ArgVectorSize =
4206+ cast<FixedVectorType>(I.getArgOperand (0 )->getType ())->getNumElements ();
4207+ assert (cast<FixedVectorType>(I.getArgOperand (1 )->getType ())
4208+ ->getNumElements () == ArgVectorSize);
4209+ assert (cast<FixedVectorType>(I.getArgOperand (2 )->getType ())
4210+ ->getNumElements () == ArgVectorSize);
4211+ assert (I.getArgOperand (0 )->getType () == I.getArgOperand (2 )->getType ());
4212+ assert (I.getType () == I.getArgOperand (0 )->getType ());
4213+ assert (I.getArgOperand (1 )->getType ()->isIntOrIntVectorTy ());
4214+ IRBuilder<> IRB (&I);
4215+ Value *AShadow = getShadow (&I, 0 );
4216+ Value *Idx = I.getArgOperand (1 );
4217+ Value *BShadow = getShadow (&I, 2 );
4218+ insertShadowCheck (Idx, &I);
4219+
4220+ // Shadows are integer-ish types but some intrinsics require a
4221+ // different (e.g., floating-point) type.
4222+ AShadow = IRB.CreateBitCast (AShadow, I.getArgOperand (0 )->getType ());
4223+ BShadow = IRB.CreateBitCast (BShadow, I.getArgOperand (2 )->getType ());
4224+ CallInst *CI = IRB.CreateIntrinsic (I.getType (), I.getIntrinsicID (),
4225+ {AShadow, Idx, BShadow});
4226+
4227+ setShadow (&I, IRB.CreateBitCast (CI, getShadowTy (&I)));
4228+ setOriginForNaryOp (I);
4229+ }
41904230
41914231 // Instrument BMI / BMI2 intrinsics.
41924232 // All of these intrinsics are Z = I(X, Y)
@@ -5132,16 +5172,52 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
51325172 assert (Success);
51335173 break ;
51345174 }
5135-
5175+ case Intrinsic::x86_avx2_permd:
5176+ case Intrinsic::x86_avx2_permps:
5177+ case Intrinsic::x86_ssse3_pshuf_b_128:
5178+ case Intrinsic::x86_avx2_pshuf_b:
5179+ case Intrinsic::x86_avx512_pshuf_b_512:
5180+ case Intrinsic::x86_avx512_permvar_df_256:
5181+ case Intrinsic::x86_avx512_permvar_df_512:
5182+ case Intrinsic::x86_avx512_permvar_di_256:
5183+ case Intrinsic::x86_avx512_permvar_di_512:
5184+ case Intrinsic::x86_avx512_permvar_hi_128:
5185+ case Intrinsic::x86_avx512_permvar_hi_256:
5186+ case Intrinsic::x86_avx512_permvar_hi_512:
5187+ case Intrinsic::x86_avx512_permvar_qi_128:
5188+ case Intrinsic::x86_avx512_permvar_qi_256:
5189+ case Intrinsic::x86_avx512_permvar_qi_512:
5190+ case Intrinsic::x86_avx512_permvar_sf_512:
5191+ case Intrinsic::x86_avx512_permvar_si_512:
51365192 case Intrinsic::x86_avx_vpermilvar_pd:
51375193 case Intrinsic::x86_avx_vpermilvar_pd_256:
51385194 case Intrinsic::x86_avx512_vpermilvar_pd_512:
51395195 case Intrinsic::x86_avx_vpermilvar_ps:
51405196 case Intrinsic::x86_avx_vpermilvar_ps_256:
51415197 case Intrinsic::x86_avx512_vpermilvar_ps_512: {
5142- handleAVXVpermilvar (I);
5198+ handleAVXPermutation (I);
51435199 break ;
51445200 }
5201+ case Intrinsic::x86_avx512_vpermi2var_d_128:
5202+ case Intrinsic::x86_avx512_vpermi2var_d_256:
5203+ case Intrinsic::x86_avx512_vpermi2var_d_512:
5204+ case Intrinsic::x86_avx512_vpermi2var_hi_128:
5205+ case Intrinsic::x86_avx512_vpermi2var_hi_256:
5206+ case Intrinsic::x86_avx512_vpermi2var_hi_512:
5207+ case Intrinsic::x86_avx512_vpermi2var_pd_128:
5208+ case Intrinsic::x86_avx512_vpermi2var_pd_256:
5209+ case Intrinsic::x86_avx512_vpermi2var_pd_512:
5210+ case Intrinsic::x86_avx512_vpermi2var_ps_128:
5211+ case Intrinsic::x86_avx512_vpermi2var_ps_256:
5212+ case Intrinsic::x86_avx512_vpermi2var_ps_512:
5213+ case Intrinsic::x86_avx512_vpermi2var_q_128:
5214+ case Intrinsic::x86_avx512_vpermi2var_q_256:
5215+ case Intrinsic::x86_avx512_vpermi2var_q_512:
5216+ case Intrinsic::x86_avx512_vpermi2var_qi_128:
5217+ case Intrinsic::x86_avx512_vpermi2var_qi_256:
5218+ case Intrinsic::x86_avx512_vpermi2var_qi_512:
5219+ handleAVXVpermil2var (I);
5220+ break ;
51455221
51465222 case Intrinsic::x86_avx512fp16_mask_add_sh_round:
51475223 case Intrinsic::x86_avx512fp16_mask_sub_sh_round:
0 commit comments