@@ -2607,25 +2607,69 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
26072607 // /
26082608 // / e.g., <2 x i32> @llvm.aarch64.neon.saddlp.v2i32.v4i16(<4 x i16>)
26092609 // / <16 x i8> @llvm.aarch64.neon.addp.v16i8(<16 x i8>, <16 x i8>)
2610- // /
2611- // / Optionally, reinterpret the parameters to have elements of a specified
2610+ void handlePairwiseShadowOrIntrinsic (IntrinsicInst &I) {
2611+ assert (I.arg_size () == 1 || I.arg_size () == 2 );
2612+
2613+ assert (I.getType ()->isVectorTy ());
2614+ assert (I.getArgOperand (0 )->getType ()->isVectorTy ());
2615+
2616+ FixedVectorType *ParamType =
2617+ cast<FixedVectorType>(I.getArgOperand (0 )->getType ());
2618+ assert ((I.arg_size () != 2 ) || (ParamType == cast<FixedVectorType>(I.getArgOperand (1 )->getType ())));
2619+ [[maybe_unused]] FixedVectorType *ReturnType =
2620+ cast<FixedVectorType>(I.getType ());
2621+ assert (ParamType->getNumElements () * I.arg_size () ==
2622+ 2 * ReturnType->getNumElements ());
2623+
2624+ IRBuilder<> IRB (&I);
2625+ unsigned Width = ParamType->getNumElements () * I.arg_size ();
2626+
2627+ // Horizontal OR of shadow
2628+ SmallVector<int , 8 > EvenMask;
2629+ SmallVector<int , 8 > OddMask;
2630+ for (unsigned X = 0 ; X < Width; X += 2 ) {
2631+ EvenMask.push_back (X);
2632+ OddMask.push_back (X + 1 );
2633+ }
2634+
2635+ Value *FirstArgShadow = getShadow (&I, 0 );
2636+ Value *EvenShadow;
2637+ Value *OddShadow;
2638+ if (I.arg_size () == 2 ) {
2639+ Value *SecondArgShadow = getShadow (&I, 1 );
2640+ EvenShadow =
2641+ IRB.CreateShuffleVector (FirstArgShadow, SecondArgShadow, EvenMask);
2642+ OddShadow =
2643+ IRB.CreateShuffleVector (FirstArgShadow, SecondArgShadow, OddMask);
2644+ } else {
2645+ EvenShadow = IRB.CreateShuffleVector (FirstArgShadow, EvenMask);
2646+ OddShadow = IRB.CreateShuffleVector (FirstArgShadow, OddMask);
2647+ }
2648+
2649+ Value *OrShadow = IRB.CreateOr (EvenShadow, OddShadow);
2650+ OrShadow = CreateShadowCast (IRB, OrShadow, getShadowTy (&I));
2651+
2652+ setShadow (&I, OrShadow);
2653+ setOriginForNaryOp (I);
2654+ }
2655+
2656+ // / Propagate shadow for 1- or 2-vector intrinsics that combine adjacent
2657+ // / fields, with the parameters reinterpreted to have elements of a specified
26122658 // / width. For example:
26132659 // / @llvm.x86.ssse3.phadd.w(<1 x i64> [[VAR1]], <1 x i64> [[VAR2]])
26142660 // / conceptually operates on
26152661 // / (<4 x i16> [[VAR1]], <4 x i16> [[VAR2]])
26162662 // / and can be handled with ReinterpretElemWidth == 16.
26172663 void
2618- handlePairwiseShadowOrIntrinsic (IntrinsicInst &I,
2619- std::optional<int > ReinterpretElemWidth) {
2664+ handlePairwiseShadowOrIntrinsic (IntrinsicInst &I, int ReinterpretElemWidth) {
26202665 assert (I.arg_size () == 1 || I.arg_size () == 2 );
26212666
26222667 assert (I.getType ()->isVectorTy ());
26232668 assert (I.getArgOperand (0 )->getType ()->isVectorTy ());
26242669
26252670 FixedVectorType *ParamType =
26262671 cast<FixedVectorType>(I.getArgOperand (0 )->getType ());
2627- if (I.arg_size () == 2 )
2628- assert (I.getArgOperand (0 )->getType () == I.getArgOperand (1 )->getType ());
2672+ assert ((I.arg_size () != 2 ) || (ParamType == cast<FixedVectorType>(I.getArgOperand (1 )->getType ())));
26292673
26302674 [[maybe_unused]] FixedVectorType *ReturnType =
26312675 cast<FixedVectorType>(I.getType ());
@@ -2636,14 +2680,12 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
26362680
26372681 unsigned TotalNumElems = ParamType->getNumElements () * I.arg_size ();
26382682 FixedVectorType *ReinterpretShadowTy = nullptr ;
2639- if (ReinterpretElemWidth.has_value ()) {
2640- assert (isAligned (Align (*ReinterpretElemWidth),
2641- ParamType->getPrimitiveSizeInBits ()));
2642- ReinterpretShadowTy = FixedVectorType::get (
2643- IRB.getIntNTy (*ReinterpretElemWidth),
2644- ParamType->getPrimitiveSizeInBits () / *ReinterpretElemWidth);
2645- TotalNumElems = ReinterpretShadowTy->getNumElements () * I.arg_size ();
2646- }
2683+ assert (isAligned (Align (ReinterpretElemWidth),
2684+ ParamType->getPrimitiveSizeInBits ()));
2685+ ReinterpretShadowTy = FixedVectorType::get (
2686+ IRB.getIntNTy (ReinterpretElemWidth),
2687+ ParamType->getPrimitiveSizeInBits () / ReinterpretElemWidth);
2688+ TotalNumElems = ReinterpretShadowTy->getNumElements () * I.arg_size ();
26472689
26482690 // Horizontal OR of shadow
26492691 SmallVector<int , 8 > EvenMask;
@@ -2654,8 +2696,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
26542696 }
26552697
26562698 Value *FirstArgShadow = getShadow (&I, 0 );
2657- if (ReinterpretShadowTy)
2658- FirstArgShadow = IRB.CreateBitCast (FirstArgShadow, ReinterpretShadowTy);
2699+ FirstArgShadow = IRB.CreateBitCast (FirstArgShadow, ReinterpretShadowTy);
26592700
26602701 // If we had two parameters each with an odd number of elements, the total
26612702 // number of elements is even, but we have never seen this in extant
@@ -2669,9 +2710,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
26692710 Value *OddShadow;
26702711 if (I.arg_size () == 2 ) {
26712712 Value *SecondArgShadow = getShadow (&I, 1 );
2672- if (ReinterpretShadowTy)
2673- SecondArgShadow =
2674- IRB.CreateBitCast (SecondArgShadow, ReinterpretShadowTy);
2713+ SecondArgShadow =
2714+ IRB.CreateBitCast (SecondArgShadow, ReinterpretShadowTy);
26752715
26762716 EvenShadow =
26772717 IRB.CreateShuffleVector (FirstArgShadow, SecondArgShadow, EvenMask);
@@ -4777,7 +4817,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
47774817 case Intrinsic::x86_sse3_hsub_pd:
47784818 case Intrinsic::x86_avx_hsub_pd_256:
47794819 case Intrinsic::x86_avx_hsub_ps_256: {
4780- handlePairwiseShadowOrIntrinsic (I, /* ReinterpretElemWidth= */ std:: nullopt );
4820+ handlePairwiseShadowOrIntrinsic (I);
47814821 break ;
47824822 }
47834823
@@ -4837,7 +4877,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
48374877 // Add Long Pairwise
48384878 case Intrinsic::aarch64_neon_saddlp:
48394879 case Intrinsic::aarch64_neon_uaddlp: {
4840- handlePairwiseShadowOrIntrinsic (I, std:: nullopt );
4880+ handlePairwiseShadowOrIntrinsic (I);
48414881 break ;
48424882 }
48434883
0 commit comments