@@ -2690,6 +2690,41 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
26902690    SC.Done (&I);
26912691  }
26922692
2693+  //  Perform a bitwise OR on the horizontal pairs (or other specified grouping)
2694+   //  of elements. This is convenient for instrumenting horizontal add/sub.
2695+   Value *horizontalReduce (IntrinsicInst &I, unsigned  ReductionFactor,
2696+                           Value *VectorA, Value* VectorB) {
2697+     IRBuilder<> IRB (&I);
2698+     assert (isa<FixedVectorType>(VectorA->getType ()));
2699+     unsigned  TotalNumElems = cast<FixedVectorType>(VectorA->getType ())->getNumElements ();
2700+ 
2701+     if  (VectorB) {
2702+       assert (VectorA->getType () == VectorB->getType ());
2703+       TotalNumElems = TotalNumElems * 2 ;
2704+     }
2705+ 
2706+     Value *Or = nullptr ;
2707+ 
2708+     for  (unsigned  i = 0 ; i < ReductionFactor; i++) {
2709+       SmallVector<int , 16 > Mask;
2710+       for  (unsigned  X = 0 ; X < TotalNumElems; X += ReductionFactor)
2711+         Mask.push_back (X + i);
2712+ 
2713+       Value *Masked;
2714+       if  (VectorB)
2715+         Masked = IRB.CreateShuffleVector (VectorA, VectorB, Mask);
2716+       else 
2717+         Masked = IRB.CreateShuffleVector (VectorA, Mask);
2718+ 
2719+       if  (Or)
2720+         Or = IRB.CreateOr (Or, Masked);
2721+       else 
2722+         Or = Masked;
2723+     }
2724+ 
2725+     return  Or;
2726+   }
2727+ 
26932728  // / Propagate shadow for 1- or 2-vector intrinsics that combine adjacent
26942729  // / fields.
26952730  // /
@@ -2711,31 +2746,16 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
27112746           2  * ReturnType->getNumElements ());
27122747
27132748    IRBuilder<> IRB (&I);
2714-     unsigned  Width = ParamType->getNumElements () * I.arg_size ();
27152749
27162750    //  Horizontal OR of shadow
2717-     SmallVector<int , 8 > EvenMask;
2718-     SmallVector<int , 8 > OddMask;
2719-     for  (unsigned  X = 0 ; X < Width; X += 2 ) {
2720-       EvenMask.push_back (X);
2721-       OddMask.push_back (X + 1 );
2722-     }
2723- 
27242751    Value *FirstArgShadow = getShadow (&I, 0 );
2725-     Value *EvenShadow;
2726-     Value *OddShadow;
2727-     if  (I.arg_size () == 2 ) {
2728-       Value *SecondArgShadow = getShadow (&I, 1 );
2729-       EvenShadow =
2730-           IRB.CreateShuffleVector (FirstArgShadow, SecondArgShadow, EvenMask);
2731-       OddShadow =
2732-           IRB.CreateShuffleVector (FirstArgShadow, SecondArgShadow, OddMask);
2733-     } else  {
2734-       EvenShadow = IRB.CreateShuffleVector (FirstArgShadow, EvenMask);
2735-       OddShadow = IRB.CreateShuffleVector (FirstArgShadow, OddMask);
2736-     }
2752+     Value *SecondArgShadow = nullptr ;
2753+     if  (I.arg_size () == 2 )
2754+       SecondArgShadow = getShadow (&I, 1 );
2755+ 
2756+     Value *OrShadow = horizontalReduce (I, /* ReductionFactor=*/   2 ,
2757+                                        FirstArgShadow, SecondArgShadow);
27372758
2738-     Value *OrShadow = IRB.CreateOr (EvenShadow, OddShadow);
27392759    OrShadow = CreateShadowCast (IRB, OrShadow, getShadowTy (&I));
27402760
27412761    setShadow (&I, OrShadow);
@@ -2768,23 +2788,14 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
27682788
27692789    IRBuilder<> IRB (&I);
27702790
2771-     unsigned  TotalNumElems = ParamType->getNumElements () * I.arg_size ();
27722791    FixedVectorType *ReinterpretShadowTy = nullptr ;
27732792    assert (isAligned (Align (ReinterpretElemWidth),
27742793                     ParamType->getPrimitiveSizeInBits ()));
27752794    ReinterpretShadowTy = FixedVectorType::get (
27762795        IRB.getIntNTy (ReinterpretElemWidth),
27772796        ParamType->getPrimitiveSizeInBits () / ReinterpretElemWidth);
2778-     TotalNumElems = ReinterpretShadowTy->getNumElements () * I.arg_size ();
27792797
27802798    //  Horizontal OR of shadow
2781-     SmallVector<int , 8 > EvenMask;
2782-     SmallVector<int , 8 > OddMask;
2783-     for  (unsigned  X = 0 ; X < TotalNumElems - 1 ; X += 2 ) {
2784-       EvenMask.push_back (X);
2785-       OddMask.push_back (X + 1 );
2786-     }
2787- 
27882799    Value *FirstArgShadow = getShadow (&I, 0 );
27892800    FirstArgShadow = IRB.CreateBitCast (FirstArgShadow, ReinterpretShadowTy);
27902801
@@ -2796,22 +2807,16 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
27962807        Align (2 ),
27972808        cast<FixedVectorType>(FirstArgShadow->getType ())->getNumElements ()));
27982809
2799-     Value *EvenShadow;
2800-     Value *OddShadow;
2810+     Value *SecondArgShadow = nullptr ;
28012811    if  (I.arg_size () == 2 ) {
2802-       Value *SecondArgShadow = getShadow (&I, 1 );
2803-       SecondArgShadow = IRB.CreateBitCast (SecondArgShadow, ReinterpretShadowTy);
2804- 
2805-       EvenShadow =
2806-           IRB.CreateShuffleVector (FirstArgShadow, SecondArgShadow, EvenMask);
2807-       OddShadow =
2808-           IRB.CreateShuffleVector (FirstArgShadow, SecondArgShadow, OddMask);
2809-     } else  {
2810-       EvenShadow = IRB.CreateShuffleVector (FirstArgShadow, EvenMask);
2811-       OddShadow = IRB.CreateShuffleVector (FirstArgShadow, OddMask);
2812+       SecondArgShadow = getShadow (&I, 1 );
2813+       SecondArgShadow = IRB.CreateBitCast (SecondArgShadow,
2814+                                           ReinterpretShadowTy);
28122815    }
28132816
2814-     Value *OrShadow = IRB.CreateOr (EvenShadow, OddShadow);
2817+     Value *OrShadow = horizontalReduce (I, /* ReductionFactor=*/   2 ,
2818+                                        FirstArgShadow, SecondArgShadow);
2819+ 
28152820    OrShadow = CreateShadowCast (IRB, OrShadow, getShadowTy (&I));
28162821
28172822    setShadow (&I, OrShadow);
0 commit comments