From dee018c51f377f46b8b2fb8507f19c51e3747fcc Mon Sep 17 00:00:00 2001 From: Davide Italiano Date: Fri, 15 Sep 2017 20:53:05 +0000 Subject: [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 --- llvm/lib/IR/ConstantFold.cpp | 13 ++++++++++++- llvm/test/Transforms/InstCombine/pr34627.ll | 11 +++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Transforms/InstCombine/pr34627.ll (limited to 'llvm') 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(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(Idxs[i]->getType())) { + GEPTy = VectorType::get(OrigGEPTy, VT->getNumElements()); + break; + } + } + return Constant::getNullValue(GEPTy); } } diff --git a/llvm/test/Transforms/InstCombine/pr34627.ll b/llvm/test/Transforms/InstCombine/pr34627.ll new file mode 100644 index 00000000000..8935ecf755c --- /dev/null +++ b/llvm/test/Transforms/InstCombine/pr34627.ll @@ -0,0 +1,11 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -instcombine %s |FileCheck %s + +define <2 x i16> @patatino() { +; CHECK-LABEL: @patatino( +; CHECK-NEXT: ret <2 x i16> zeroinitializer +; + %tmp2 = getelementptr inbounds [1 x i16], [1 x i16]* null, i16 0, <2 x i16> undef + %tmp3 = ptrtoint <2 x i16*> %tmp2 to <2 x i16> + ret <2 x i16> %tmp3 +} -- cgit v1.2.3