Index: lib/Transforms/Vectorize/LoopVectorize.cpp =================================================================== --- lib/Transforms/Vectorize/LoopVectorize.cpp +++ lib/Transforms/Vectorize/LoopVectorize.cpp @@ -1556,25 +1556,61 @@ if (!Gep) return 0; - unsigned NumOperands = Gep->getNumOperands(); - Value *GpPtr = Gep->getPointerOperand(); - // If this GEP value is a consecutive pointer induction variable and all of - // the indices are constant then we know it is consecutive. We can - Phi = dyn_cast(GpPtr); - if (Phi && Inductions.count(Phi)) { + const DataLayout &DL = Gep->getModule()->getDataLayout(); + unsigned GEPAllocSize = DL.getTypeAllocSize( + cast(Gep->getType()->getScalarType())->getElementType()); - // Make sure that the pointer does not point to structs. - PointerType *GepPtrType = cast(GpPtr->getType()); - if (GepPtrType->getElementType()->isAggregateType()) - return 0; + unsigned NumOperands; + while (Gep) { + NumOperands = Gep->getNumOperands(); + Value *GpPtr = Gep->getPointerOperand(); + Phi = dyn_cast(GpPtr); + if (Phi && Inductions.count(Phi)) { + // If this GEP value is a consecutive pointer induction variable and + // all of the indices are constant then we know it is consecutive. + + // Make sure that the pointer does not point to structs. + PointerType *GepPtrType = cast(GpPtr->getType()); + + // Make sure that all of the index operands are loop invariant. + for (unsigned i = 1; i < NumOperands; ++i) + if (!SE->isLoopInvariant(SE->getSCEV(Gep->getOperand(i)), TheLoop)) + return 0; - // Make sure that all of the index operands are loop invariant. - for (unsigned i = 1; i < NumOperands; ++i) - if (!SE->isLoopInvariant(SE->getSCEV(Gep->getOperand(i)), TheLoop)) - return 0; + if (GepPtrType->getElementType()->isAggregateType()) { + if ((Gep = dyn_cast(GpPtr))) + continue; + else + return 0; + } + InductionInfo II = Inductions[Phi]; + return II.getConsecutiveDirection(); + } else { + // If the pointer operand of the GEP is a SCEVAddRecExpr, and all the + // other operand is 0, and the pointer operand is another + // GetElementPtrInst, recursively find the induction variable in the + // pointer operand. + const SCEV *PtrScev = SE->getSCEV(GpPtr); + if (dyn_cast(PtrScev)) { + for (unsigned i = 1; i < NumOperands; ++i) + if (!match(Gep->getOperand(i), m_Zero())) + return 0; + + Gep = dyn_cast(GpPtr); + if (!Gep) + return 0; + + unsigned NewAllocSize = DL.getTypeAllocSize( + cast(Gep->getType()->getScalarType()) + ->getElementType()); + if (GEPAllocSize != NewAllocSize) + return 0; - InductionInfo II = Inductions[Phi]; - return II.getConsecutiveDirection(); + continue; + } else { + break; + } + } } unsigned InductionOperand = getGEPInductionOperand(Gep); @@ -1696,8 +1732,14 @@ VectorParts &Entry = WidenMap.get(Instr); // Handle consecutive loads/stores. + Value *GepPtr; + Instruction *GepPtrInst; GetElementPtrInst *Gep = dyn_cast(Ptr); - if (Gep && Legal->isInductionVariable(Gep->getPointerOperand())) { + if (Gep && (GepPtr = Gep->getPointerOperand()) && + (GepPtrInst = dyn_cast(GepPtr)) && + !SE->isLoopInvariant(SE->getSCEV(GepPtrInst), OrigLoop)) { + // The case Gep->getPointerOperand() is an induction variable + // or a SCEVAddRecExpr. setDebugLocFromInst(Builder, Gep); Value *PtrOperand = Gep->getPointerOperand(); Value *FirstBasePtr = getVectorValue(PtrOperand)[0];