diff options
| author | Elena Demikhovsky <elena.demikhovsky@intel.com> | 2016-07-07 06:06:46 +0000 |
|---|---|---|
| committer | Elena Demikhovsky <elena.demikhovsky@intel.com> | 2016-07-07 06:06:46 +0000 |
| commit | fc1e969dfc94e0e78cc1bd3b3ebd5e81bbb56ffb (patch) | |
| tree | f7e623df93d82930d1ed502bd3c6baea671abc75 /llvm/lib | |
| parent | a54fe1acdc2df47c80f1eb319d7f8bcd65018aa9 (diff) | |
| download | bcm5719-llvm-fc1e969dfc94e0e78cc1bd3b3ebd5e81bbb56ffb.tar.gz bcm5719-llvm-fc1e969dfc94e0e78cc1bd3b3ebd5e81bbb56ffb.zip | |
Fixed a bug in vectorizing GEP before gather/scatter intrinsic.
Vectorizing GEP was incorrect and broke SSA in some cases.
The patch fixes PR27997 https://llvm.org/bugs/show_bug.cgi?id=27997.
Differential revision: http://reviews.llvm.org/D22035
llvm-svn: 274735
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index fbe042118de..38ddeede84a 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -2786,24 +2786,27 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(Instruction *Instr) { // At this point we should vector version of GEP for Gather or Scatter assert(CreateGatherScatter && "The instruction should be scalarized"); if (Gep) { + // Vectorizing GEP, across UF parts. We want to get a vector value for base + // and each index that's defined inside the loop, even if it is + // loop-invariant but wasn't hoisted out. Otherwise we want to keep them + // scalar. SmallVector<VectorParts, 4> OpsV; - // Vectorizing GEP, across UF parts, we want to keep each loop-invariant - // base or index of GEP scalar for (Value *Op : Gep->operands()) { - if (PSE.getSE()->isLoopInvariant(PSE.getSCEV(Op), OrigLoop)) - OpsV.push_back(VectorParts(UF, Op)); - else + Instruction *SrcInst = dyn_cast<Instruction>(Op); + if (SrcInst && OrigLoop->contains(SrcInst)) OpsV.push_back(getVectorValue(Op)); + else + OpsV.push_back(VectorParts(UF, Op)); } - for (unsigned Part = 0; Part < UF; ++Part) { SmallVector<Value *, 4> Ops; Value *GEPBasePtr = OpsV[0][Part]; for (unsigned i = 1; i < Gep->getNumOperands(); i++) Ops.push_back(OpsV[i][Part]); - Value *NewGep = - Builder.CreateGEP(nullptr, GEPBasePtr, Ops, "VectorGep"); + Value *NewGep = Builder.CreateGEP(GEPBasePtr, Ops, "VectorGep"); + cast<GetElementPtrInst>(NewGep)->setIsInBounds(Gep->isInBounds()); assert(NewGep->getType()->isVectorTy() && "Expected vector GEP"); + NewGep = Builder.CreateBitCast(NewGep, VectorType::get(Ptr->getType(), VF)); VectorGep.push_back(NewGep); |

