summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorElena Demikhovsky <elena.demikhovsky@intel.com>2015-07-09 07:42:48 +0000
committerElena Demikhovsky <elena.demikhovsky@intel.com>2015-07-09 07:42:48 +0000
commit37a4da825f3fc3845cb66e46b9bead240666955c (patch)
tree5dc5f19ab4f2fc4906253f87f8e940dc739fb133 /llvm/lib/CodeGen
parent16c4403a91c71ce44645c1a8ad797ffb6a6e1f0a (diff)
downloadbcm5719-llvm-37a4da825f3fc3845cb66e46b9bead240666955c.tar.gz
bcm5719-llvm-37a4da825f3fc3845cb66e46b9bead240666955c.zip
Extended syntax of vector version of getelementptr instruction.
The justification of this change is here: http://lists.cs.uiuc.edu/pipermail/llvmdev/2015-March/082989.html According to the current GEP syntax, vector GEP requires that each index must be a vector with the same number of elements. %A = getelementptr i8, <4 x i8*> %ptrs, <4 x i64> %offsets In this implementation I let each index be or vector or scalar. All vector indices must have the same number of elements. The scalar value will mean the splat vector value. (1) %A = getelementptr i8, i8* %ptr, <4 x i64> %offsets or (2) %A = getelementptr i8, <4 x i8*> %ptrs, i64 %offset In all cases the %A type is <4 x i8*> In the case (2) we add the same offset to all pointers. The case (1) covers C[B[i]] case, when we have the same base C and different offsets B[i]. The documentation is updated. http://reviews.llvm.org/D10496 llvm-svn: 241788
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp29
1 files changed, 26 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 4f0fc6e1eb5..345bd0ae2dc 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2787,6 +2787,16 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
SDValue N = getValue(Op0);
SDLoc dl = getCurSDLoc();
+ // Normalize Vector GEP - all scalar operands should be converted to the
+ // splat vector.
+ unsigned VectorWidth = I.getType()->isVectorTy() ?
+ cast<VectorType>(I.getType())->getVectorNumElements() : 0;
+
+ if (VectorWidth && !N.getValueType().isVector()) {
+ MVT VT = MVT::getVectorVT(N.getValueType().getSimpleVT(), VectorWidth);
+ SmallVector<SDValue, 16> Ops(VectorWidth, N);
+ N = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops);
+ }
for (GetElementPtrInst::const_op_iterator OI = I.op_begin()+1, E = I.op_end();
OI != E; ++OI) {
const Value *Idx = *OI;
@@ -2807,12 +2817,20 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
unsigned PtrSize = PtrTy.getSizeInBits();
APInt ElementSize(PtrSize, DL->getTypeAllocSize(Ty));
- // If this is a constant subscript, handle it quickly.
- if (const auto *CI = dyn_cast<ConstantInt>(Idx)) {
+ // If this is a scalar constant or a splat vector of constants,
+ // handle it quickly.
+ const auto *CI = dyn_cast<ConstantInt>(Idx);
+ if (!CI && isa<ConstantDataVector>(Idx) &&
+ cast<ConstantDataVector>(Idx)->getSplatValue())
+ CI = cast<ConstantInt>(cast<ConstantDataVector>(Idx)->getSplatValue());
+
+ if (CI) {
if (CI->isZero())
continue;
APInt Offs = ElementSize * CI->getValue().sextOrTrunc(PtrSize);
- SDValue OffsVal = DAG.getConstant(Offs, dl, PtrTy);
+ SDValue OffsVal = VectorWidth ?
+ DAG.getConstant(Offs, dl, MVT::getVectorVT(PtrTy, VectorWidth)) :
+ DAG.getConstant(Offs, dl, PtrTy);
N = DAG.getNode(ISD::ADD, dl, N.getValueType(), N, OffsVal);
continue;
}
@@ -2820,6 +2838,11 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
// N = N + Idx * ElementSize;
SDValue IdxN = getValue(Idx);
+ if (!IdxN.getValueType().isVector() && VectorWidth) {
+ MVT VT = MVT::getVectorVT(IdxN.getValueType().getSimpleVT(), VectorWidth);
+ SmallVector<SDValue, 16> Ops(VectorWidth, IdxN);
+ IdxN = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops);
+ }
// If the index is smaller or larger than intptr_t, truncate or extend
// it.
IdxN = DAG.getSExtOrTrunc(IdxN, dl, N.getValueType());
OpenPOWER on IntegriCloud