From f79c5ce90bae0f60ffa44491a6eccf5af18deb60 Mon Sep 17 00:00:00 2001 From: Elena Demikhovsky Date: Sun, 15 Nov 2015 08:19:35 +0000 Subject: [PATCH] Fixed GEP visitor in the InstCombine pass. The current implementation of GEP visitor in InstCombine fails with assertion on Vector GEP with mix of scalar and vector types, like this: getelementptr double, double* %a, <8 x i32> %i (It fails to create a "sext" from <8 x i32> to <8 x i64>) I fixed it and added some tests. Differential Revision: http://reviews.llvm.org/D14485 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253162 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstructionCombining.cpp | 15 +++++++++----- test/Transforms/InstCombine/vector_gep2.ll | 23 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index f024ab1795e..3ae7f08238b 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1355,7 +1355,8 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { // Eliminate unneeded casts for indices, and replace indices which displace // by multiples of a zero size type with zero. bool MadeChange = false; - Type *IntPtrTy = DL.getIntPtrType(GEP.getPointerOperandType()); + Type *IntPtrTy = + DL.getIntPtrType(GEP.getPointerOperandType()->getScalarType()); gep_type_iterator GTI = gep_type_begin(GEP); for (User::op_iterator I = GEP.op_begin() + 1, E = GEP.op_end(); I != E; @@ -1365,21 +1366,25 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { if (!SeqTy) continue; + // Index type should have the same width as IntPtr + Type *IndexTy = (*I)->getType(); + Type *NewIndexType = IndexTy->isVectorTy() ? + VectorType::get(IntPtrTy, IndexTy->getVectorNumElements()) : IntPtrTy; + // If the element type has zero size then any index over it is equivalent // to an index of zero, so replace it with zero if it is not zero already. if (SeqTy->getElementType()->isSized() && DL.getTypeAllocSize(SeqTy->getElementType()) == 0) if (!isa(*I) || !cast(*I)->isNullValue()) { - *I = Constant::getNullValue(IntPtrTy); + *I = Constant::getNullValue(NewIndexType); MadeChange = true; } - Type *IndexTy = (*I)->getType(); - if (IndexTy != IntPtrTy) { + if (IndexTy != NewIndexType) { // If we are using a wider index than needed for this platform, shrink // it to what we need. If narrower, sign-extend it to what we need. // This explicit cast can make subsequent optimizations more obvious. - *I = Builder->CreateIntCast(*I, IntPtrTy, true); + *I = Builder->CreateIntCast(*I, NewIndexType, true); MadeChange = true; } } diff --git a/test/Transforms/InstCombine/vector_gep2.ll b/test/Transforms/InstCombine/vector_gep2.ll index d76a7d56cc7..1b80ffd101c 100644 --- a/test/Transforms/InstCombine/vector_gep2.ll +++ b/test/Transforms/InstCombine/vector_gep2.ll @@ -9,3 +9,26 @@ define <2 x i8*> @testa(<2 x i8*> %a) { ; CHECK: getelementptr i8, <2 x i8*> %a, <2 x i64> ret <2 x i8*> %g } + +define <8 x double*> @vgep_s_v8i64(double* %a, <8 x i64>%i) { +; CHECK-LABEL: @vgep_s_v8i64 +; CHECK: getelementptr double, double* %a, <8 x i64> %i + %VectorGep = getelementptr double, double* %a, <8 x i64> %i + ret <8 x double*> %VectorGep +} + +define <8 x double*> @vgep_s_v8i32(double* %a, <8 x i32>%i) { +; CHECK-LABEL: @vgep_s_v8i32 +; CHECK: %1 = sext <8 x i32> %i to <8 x i64> +; CHECK: getelementptr double, double* %a, <8 x i64> %1 + %VectorGep = getelementptr double, double* %a, <8 x i32> %i + ret <8 x double*> %VectorGep +} + +define <8 x i8*> @vgep_v8iPtr_i32(<8 x i8*> %a, i32 %i) { +; CHECK-LABEL: @vgep_v8iPtr_i32 +; CHECK: %1 = sext i32 %i to i64 +; CHECK: %VectorGep = getelementptr i8, <8 x i8*> %a, i64 %1 + %VectorGep = getelementptr i8, <8 x i8*> %a, i32 %i + ret <8 x i8*> %VectorGep +} -- 2.11.0