From fc1e969dfc94e0e78cc1bd3b3ebd5e81bbb56ffb Mon Sep 17 00:00:00 2001 From: Elena Demikhovsky Date: Thu, 7 Jul 2016 06:06:46 +0000 Subject: 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 --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'llvm/lib') 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 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(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 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(NewGep)->setIsInBounds(Gep->isInBounds()); assert(NewGep->getType()->isVectorTy() && "Expected vector GEP"); + NewGep = Builder.CreateBitCast(NewGep, VectorType::get(Ptr->getType(), VF)); VectorGep.push_back(NewGep); -- cgit v1.2.3