diff options
author | Davide Italiano <davide@freebsd.org> | 2017-09-15 20:53:05 +0000 |
---|---|---|
committer | Davide Italiano <davide@freebsd.org> | 2017-09-15 20:53:05 +0000 |
commit | dee018c51f377f46b8b2fb8507f19c51e3747fcc (patch) | |
tree | 8eb433af6fbcae9936101d03833169c289a27714 /llvm/lib/IR/ConstantFold.cpp | |
parent | 66a99e41cdc8d1ddd67860f7d97d861f654f1dbd (diff) | |
download | bcm5719-llvm-dee018c51f377f46b8b2fb8507f19c51e3747fcc.tar.gz bcm5719-llvm-dee018c51f377f46b8b2fb8507f19c51e3747fcc.zip |
[ConstantFold] Return the correct type when folding a GEP with vector indices.
As Eli pointed out (and I got wrong in the first place), langref says: "The
getelementptr returns a vector of pointers, instead of a single address, when one
or more of its arguments is a vector. In such cases, all vector arguments should
have the same number of elements, and every scalar argument will be effectively
broadcast into a vector during address calculation."
Costantfold for gep doesn't really take in account this paragraph, returning a
pointer instead of a vector of pointer which triggers an assertion in RAUW,
as we're trying to replace values with mistmatching types.
Differential Revision: https://reviews.llvm.org/D37928
llvm-svn: 313394
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
-rw-r--r-- | llvm/lib/IR/ConstantFold.cpp | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 311b0a76ce8..60dd20e4659 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -2062,9 +2062,20 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C, Type *Ty = GetElementPtrInst::getIndexedType(PointeeTy, Idxs); assert(Ty && "Invalid indices for GEP!"); + Type *OrigGEPTy = PointerType::get(Ty, PtrTy->getAddressSpace()); Type *GEPTy = PointerType::get(Ty, PtrTy->getAddressSpace()); if (VectorType *VT = dyn_cast<VectorType>(C->getType())) - GEPTy = VectorType::get(GEPTy, VT->getNumElements()); + GEPTy = VectorType::get(OrigGEPTy, VT->getNumElements()); + + // The GEP returns a vector of pointers when one of more of + // its arguments is a vector. + for (unsigned i = 0, e = Idxs.size(); i != e; ++i) { + if (auto *VT = dyn_cast<VectorType>(Idxs[i]->getType())) { + GEPTy = VectorType::get(OrigGEPTy, VT->getNumElements()); + break; + } + } + return Constant::getNullValue(GEPTy); } } |