@@ -2783,44 +2783,35 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(Instruction *Instr) {
2783
2783
// Handle consecutive loads/stores.
2784
2784
GetElementPtrInst *Gep = getGEPInstruction (Ptr);
2785
2785
if (ConsecutiveStride) {
2786
- if (Gep && Legal->isInductionVariable (Gep->getPointerOperand ())) {
2787
- setDebugLocFromInst (Builder, Gep);
2788
- auto *FirstBasePtr = getScalarValue (Gep->getPointerOperand (), 0 , 0 );
2789
-
2790
- // Create the new GEP with the new induction variable.
2791
- GetElementPtrInst *Gep2 = cast<GetElementPtrInst>(Gep->clone ());
2792
- Gep2->setOperand (0 , FirstBasePtr);
2793
- Gep2->setName (" gep.indvar.base" );
2794
- Ptr = Builder.Insert (Gep2);
2795
- } else if (Gep) {
2796
- setDebugLocFromInst (Builder, Gep);
2797
- assert (PSE.getSE ()->isLoopInvariant (PSE.getSCEV (Gep->getPointerOperand ()),
2798
- OrigLoop) &&
2799
- " Base ptr must be invariant" );
2800
- // The last index does not have to be the induction. It can be
2801
- // consecutive and be a function of the index. For example A[I+1];
2786
+ if (Gep) {
2802
2787
unsigned NumOperands = Gep->getNumOperands ();
2803
- unsigned InductionOperand = getGEPInductionOperand (Gep);
2804
- // Create the new GEP with the new induction variable.
2788
+ #ifndef NDEBUG
2789
+ // The original GEP that identified as a consecutive memory access
2790
+ // should have only one loop-variant operand.
2791
+ unsigned NumOfLoopVariantOps = 0 ;
2792
+ for (unsigned i = 0 ; i < NumOperands; ++i)
2793
+ if (!PSE.getSE ()->isLoopInvariant (PSE.getSCEV (Gep->getOperand (i)),
2794
+ OrigLoop))
2795
+ NumOfLoopVariantOps++;
2796
+ assert (NumOfLoopVariantOps == 1 &&
2797
+ " Consecutive GEP should have only one loop-variant operand" );
2798
+ #endif
2805
2799
GetElementPtrInst *Gep2 = cast<GetElementPtrInst>(Gep->clone ());
2806
-
2807
- for (unsigned i = 0 ; i < NumOperands; ++i) {
2808
- Value *GepOperand = Gep->getOperand (i);
2809
- Instruction *GepOperandInst = dyn_cast<Instruction>(GepOperand);
2810
-
2811
- // Update last index or loop invariant instruction anchored in loop.
2812
- if (i == InductionOperand ||
2813
- (GepOperandInst && OrigLoop->contains (GepOperandInst))) {
2814
- assert ((i == InductionOperand ||
2815
- PSE.getSE ()->isLoopInvariant (PSE.getSCEV (GepOperandInst),
2816
- OrigLoop)) &&
2817
- " Must be last index or loop invariant" );
2818
-
2819
- Gep2->setOperand (i, getScalarValue (GepOperand, 0 , 0 ));
2820
- Gep2->setName (" gep.indvar.idx" );
2821
- }
2822
- }
2800
+ Gep2->setName (" gep.indvar" );
2801
+
2802
+ // A new GEP is created for a 0-lane value of the first unroll iteration.
2803
+ // The GEPs for the rest of the unroll iterations are computed below as an
2804
+ // offset from this GEP.
2805
+ for (unsigned i = 0 ; i < NumOperands; ++i)
2806
+ // We can apply getScalarValue() for all GEP indices. It returns an
2807
+ // original value for loop-invariant operand and 0-lane for consecutive
2808
+ // operand.
2809
+ Gep2->setOperand (i, getScalarValue (Gep->getOperand (i),
2810
+ 0 , /* First unroll iteration */
2811
+ 0 /* 0-lane of the vector */ ));
2812
+ setDebugLocFromInst (Builder, Gep);
2823
2813
Ptr = Builder.Insert (Gep2);
2814
+
2824
2815
} else { // No GEP
2825
2816
// Use the induction element ptr.
2826
2817
assert (isa<PHINode>(Ptr) && " Invalid induction ptr" );
0 commit comments