@@ -3172,7 +3172,31 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
3172
3172
setOriginForNaryOp (I);
3173
3173
}
3174
3174
3175
- // Instrument vector convert intrinsic.
3175
+ // / Handle Arm NEON vector convert intrinsics.
3176
+ // /
3177
+ // / e.g., <4 x i32> @llvm.aarch64.neon.fcvtpu.v4i32.v4f32(<4 x float>)
3178
+ // / i32 @llvm.aarch64.neon.fcvtms.i32.f64(double)
3179
+ // /
3180
+ // / For x86 SSE vector convert intrinsics, see
3181
+ // / handleSSEVectorConvertIntrinsic().
3182
+ void handleNEONVectorConvertIntrinsic (IntrinsicInst &I) {
3183
+ assert (I.arg_size () == 1 );
3184
+
3185
+ IRBuilder<> IRB (&I);
3186
+ Value *S0 = getShadow (&I, 0 );
3187
+
3188
+ // / For scalars:
3189
+ // / Since they are converting from floating-point to integer, the output is
3190
+ // / - fully uninitialized if *any* bit of the input is uninitialized
3191
+ // / - fully ininitialized if all bits of the input are ininitialized
3192
+ // / We apply the same principle on a per-field basis for vectors.
3193
+ Value *OutShadow = IRB.CreateSExt (IRB.CreateICmpNE (S0, getCleanShadow (S0)),
3194
+ getShadowTy (&I));
3195
+ setShadow (&I, OutShadow);
3196
+ setOriginForNaryOp (I);
3197
+ }
3198
+
3199
+ // Instrument x86 SSE vector convert intrinsic.
3176
3200
//
3177
3201
// This function instruments intrinsics like cvtsi2ss:
3178
3202
// %Out = int_xxx_cvtyyy(%ConvertOp)
@@ -3187,8 +3211,11 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
3187
3211
// We copy the shadow of \p CopyOp[NumUsedElements:] to \p
3188
3212
// Out[NumUsedElements:]. This means that intrinsics without \p CopyOp always
3189
3213
// return a fully initialized value.
3190
- void handleVectorConvertIntrinsic (IntrinsicInst &I, int NumUsedElements,
3191
- bool HasRoundingMode = false ) {
3214
+ //
3215
+ // For Arm NEON vector convert intrinsics, see
3216
+ // handleNEONVectorConvertIntrinsic().
3217
+ void handleSSEVectorConvertIntrinsic (IntrinsicInst &I, int NumUsedElements,
3218
+ bool HasRoundingMode = false ) {
3192
3219
IRBuilder<> IRB (&I);
3193
3220
Value *CopyOp, *ConvertOp;
3194
3221
@@ -4477,7 +4504,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
4477
4504
case Intrinsic::x86_avx512_cvtusi2ss:
4478
4505
case Intrinsic::x86_avx512_cvtusi642sd:
4479
4506
case Intrinsic::x86_avx512_cvtusi642ss:
4480
- handleVectorConvertIntrinsic (I, 1 , true );
4507
+ handleSSEVectorConvertIntrinsic (I, 1 , true );
4481
4508
break ;
4482
4509
case Intrinsic::x86_sse2_cvtsd2si64:
4483
4510
case Intrinsic::x86_sse2_cvtsd2si:
@@ -4488,11 +4515,11 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
4488
4515
case Intrinsic::x86_sse_cvtss2si:
4489
4516
case Intrinsic::x86_sse_cvttss2si64:
4490
4517
case Intrinsic::x86_sse_cvttss2si:
4491
- handleVectorConvertIntrinsic (I, 1 );
4518
+ handleSSEVectorConvertIntrinsic (I, 1 );
4492
4519
break ;
4493
4520
case Intrinsic::x86_sse_cvtps2pi:
4494
4521
case Intrinsic::x86_sse_cvttps2pi:
4495
- handleVectorConvertIntrinsic (I, 2 );
4522
+ handleSSEVectorConvertIntrinsic (I, 2 );
4496
4523
break ;
4497
4524
4498
4525
case Intrinsic::x86_avx512_psll_w_512:
@@ -4846,6 +4873,27 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
4846
4873
break ;
4847
4874
}
4848
4875
4876
+ // Floating-point Convert to integer, rounding to nearest with ties to Away
4877
+ case Intrinsic::aarch64_neon_fcvtas:
4878
+ case Intrinsic::aarch64_neon_fcvtau:
4879
+ // Floating-point convert to integer, rounding toward minus infinity
4880
+ case Intrinsic::aarch64_neon_fcvtms:
4881
+ case Intrinsic::aarch64_neon_fcvtmu:
4882
+ // Floating-point convert to integer, rounding to nearest with ties to even
4883
+ case Intrinsic::aarch64_neon_fcvtns:
4884
+ case Intrinsic::aarch64_neon_fcvtnu:
4885
+ // Floating-point convert to integer, rounding toward plus infinity
4886
+ case Intrinsic::aarch64_neon_fcvtps:
4887
+ case Intrinsic::aarch64_neon_fcvtpu:
4888
+ // Floating-point Convert to integer, rounding toward Zero
4889
+ case Intrinsic::aarch64_neon_fcvtzs:
4890
+ case Intrinsic::aarch64_neon_fcvtzu:
4891
+ // Floating-point convert to lower precision narrow, rounding to odd
4892
+ case Intrinsic::aarch64_neon_fcvtxn: {
4893
+ handleNEONVectorConvertIntrinsic (I);
4894
+ break ;
4895
+ }
4896
+
4849
4897
case Intrinsic::aarch64_neon_st1x2:
4850
4898
case Intrinsic::aarch64_neon_st1x3:
4851
4899
case Intrinsic::aarch64_neon_st1x4:
0 commit comments