diff options
author | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-12-23 14:45:00 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-12-23 14:45:00 +0000 |
commit | 3548cbb98044c569e6fef10d6b9a1b6c68c8bbf7 (patch) | |
tree | 9970d5e556e164816339169230f1589475a3f402 /llvm/lib/Transforms/Scalar/Scalarizer.cpp | |
parent | 530e207d8a1eb487f0912e467bac98a83528d766 (diff) | |
download | bcm5719-llvm-3548cbb98044c569e6fef10d6b9a1b6c68c8bbf7.tar.gz bcm5719-llvm-3548cbb98044c569e6fef10d6b9a1b6c68c8bbf7.zip |
Fix Scalarizer handling of vector GEPs with multiple index operands
The old code only worked for one index operand. Also handle "inbounds".
llvm-svn: 197908
Diffstat (limited to 'llvm/lib/Transforms/Scalar/Scalarizer.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/Scalarizer.cpp | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/llvm/lib/Transforms/Scalar/Scalarizer.cpp b/llvm/lib/Transforms/Scalar/Scalarizer.cpp index 36a01bd81df..33ccb7350d8 100644 --- a/llvm/lib/Transforms/Scalar/Scalarizer.cpp +++ b/llvm/lib/Transforms/Scalar/Scalarizer.cpp @@ -42,6 +42,8 @@ typedef SmallVector<std::pair<Instruction *, ValueVector *>, 16> GatherList; // component of a scattered vector or vector pointer. class Scatterer { public: + Scatterer() {} + // Scatter V into Size components. If new instructions are needed, // insert them before BBI in BB. If Cache is nonnull, use it to cache // the results. @@ -97,16 +99,6 @@ struct BinarySplitter { BinaryOperator &BO; }; -// GEPSpliiter()(Builder, X, Y, Name) uses Builder to create -// a single GEP called Name with operands X and Y. -struct GEPSplitter { - GEPSplitter() {} - Value *operator()(IRBuilder<> &Builder, Value *Op0, Value *Op1, - const Twine &Name) const { - return Builder.CreateGEP(Op0, Op1, Name); - } -}; - // Information about a load or store that we're scalarizing. struct VectorLayout { VectorLayout() : VecTy(0), ElemTy(0), VecAlign(0), ElemSize(0) {} @@ -429,7 +421,36 @@ bool Scalarizer::visitBinaryOperator(BinaryOperator &BO) { } bool Scalarizer::visitGetElementPtrInst(GetElementPtrInst &GEPI) { - return splitBinary(GEPI, GEPSplitter()); + VectorType *VT = dyn_cast<VectorType>(GEPI.getType()); + if (!VT) + return false; + + IRBuilder<> Builder(GEPI.getParent(), &GEPI); + unsigned NumElems = VT->getNumElements(); + unsigned NumIndices = GEPI.getNumIndices(); + + Scatterer Base = scatter(&GEPI, GEPI.getOperand(0)); + + SmallVector<Scatterer, 8> Ops; + Ops.resize(NumIndices); + for (unsigned I = 0; I < NumIndices; ++I) + Ops[I] = scatter(&GEPI, GEPI.getOperand(I + 1)); + + ValueVector Res; + Res.resize(NumElems); + for (unsigned I = 0; I < NumElems; ++I) { + SmallVector<Value *, 8> Indices; + Indices.resize(NumIndices); + for (unsigned J = 0; J < NumIndices; ++J) + Indices[J] = Ops[J][I]; + Res[I] = Builder.CreateGEP(Base[I], Indices, + GEPI.getName() + ".i" + Twine(I)); + if (GEPI.isInBounds()) + if (GetElementPtrInst *NewGEPI = dyn_cast<GetElementPtrInst>(Res[I])) + NewGEPI->setIsInBounds(); + } + gather(&GEPI, Res); + return true; } bool Scalarizer::visitCastInst(CastInst &CI) { |