Index: ../lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- ../lib/Transforms/InstCombine/InstructionCombining.cpp +++ ../lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1355,7 +1355,8 @@ // 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 @@ 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; } } Index: ../test/Transforms/InstCombine/vector_gep2.ll =================================================================== --- ../test/Transforms/InstCombine/vector_gep2.ll +++ ../test/Transforms/InstCombine/vector_gep2.ll @@ -9,3 +9,26 @@ ; 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 +}