diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -2175,15 +2175,20 @@ std::vector ArgVec; ArgVec.reserve(1 + Idxs.size()); ArgVec.push_back(C); - for (unsigned i = 0, e = Idxs.size(); i != e; ++i) { + auto GTI = gep_type_begin(Ty, Idxs), GTE = gep_type_end(Ty, Idxs); + for (; GTI != GTE; ++GTI) { + auto *Idx = cast(GTI.getOperand()); assert( - (!isa(Idxs[i]->getType()) || - cast(Idxs[i]->getType())->getElementCount() == EltCount) && + (!isa(Idx->getType()) || + cast(Idx->getType())->getElementCount() == EltCount) && "getelementptr index type missmatch"); - Constant *Idx = cast(Idxs[i]); - if (EltCount.Min != 0 && !Idxs[i]->getType()->isVectorTy()) + if (GTI.isStruct() && Idx->getType()->isVectorTy()) { + Idx = Idx->getSplatValue(); + } else if (GTI.isSequential() && EltCount.Min != 0 && + !Idx->getType()->isVectorTy()) { Idx = ConstantVector::getSplat(EltCount, Idx); + } ArgVec.push_back(Idx); } diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp --- a/llvm/lib/IR/DataLayout.cpp +++ b/llvm/lib/IR/DataLayout.cpp @@ -814,7 +814,7 @@ unsigned NumBits = getIndexTypeSizeInBits(Ty); IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits); if (VectorType *VecTy = dyn_cast(Ty)) - return FixedVectorType::get(IntTy, VecTy->getNumElements()); + return VectorType::get(IntTy, VecTy); return IntTy; } diff --git a/llvm/test/Analysis/ConstantFolding/vectorgep-crash.ll b/llvm/test/Analysis/ConstantFolding/vectorgep-crash.ll --- a/llvm/test/Analysis/ConstantFolding/vectorgep-crash.ll +++ b/llvm/test/Analysis/ConstantFolding/vectorgep-crash.ll @@ -24,7 +24,7 @@ @G = internal global [65 x %struct.A] zeroinitializer, align 16 ; CHECK-LABEL: @test -; CHECK: ret <16 x i32*> getelementptr ([65 x %struct.A], [65 x %struct.A]* @G, <16 x i64> zeroinitializer, <16 x i64> , <16 x i32> zeroinitializer) +; CHECK: ret <16 x i32*> getelementptr ([65 x %struct.A], [65 x %struct.A]* @G, <16 x i64> zeroinitializer, <16 x i64> , i32 0) define <16 x i32*> @test() { vector.body: %VectorGep = getelementptr [65 x %struct.A], [65 x %struct.A]* @G, <16 x i64> zeroinitializer, <16 x i64> , <16 x i32> zeroinitializer diff --git a/llvm/test/Transforms/InstSimplify/gep.ll b/llvm/test/Transforms/InstSimplify/gep.ll --- a/llvm/test/Transforms/InstSimplify/gep.ll +++ b/llvm/test/Transforms/InstSimplify/gep.ll @@ -152,7 +152,7 @@ %struct = type { double, float } define <4 x float*> @vector_idx_mix_scalar_vector() { ; CHECK-LABEL: @vector_idx_mix_scalar_vector( -; CHECK-NEXT: ret <4 x float*> getelementptr (%struct, <4 x %struct*> zeroinitializer, <4 x i64> zeroinitializer, <4 x i32> ) +; CHECK-NEXT: ret <4 x float*> getelementptr (%struct, <4 x %struct*> zeroinitializer, <4 x i64> zeroinitializer, i32 1) ; %gep = getelementptr %struct, <4 x %struct*> zeroinitializer, i32 0, <4 x i32> ret <4 x float*> %gep @@ -168,4 +168,12 @@ ret %gep } +define @scalable_vector_idx_mix_scalar_vector() { +; CHECK-LABEL: @scalable_vector_idx_mix_scalar_vector( +; CHECK-NEXT: ret getelementptr (%struct, zeroinitializer, zeroinitializer, i32 1) +; + %gep = getelementptr %struct, zeroinitializer, i32 0, i32 1 + ret %gep +} + ; Check ConstantExpr::getGetElementPtr() using ElementCount for size queries - end.