diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4321,10 +4321,14 @@ // Compute the (pointer) type returned by the GEP instruction. Type *LastType = GetElementPtrInst::getIndexedType(SrcTy, Ops.slice(1)); Type *GEPTy = PointerType::get(LastType, AS); - if (VectorType *VT = dyn_cast(Ops[0]->getType())) - GEPTy = VectorType::get(GEPTy, VT->getElementCount()); - else if (VectorType *VT = dyn_cast(Ops[1]->getType())) - GEPTy = VectorType::get(GEPTy, VT->getElementCount()); + for (Value *Op : Ops) { + // If one of the operands is a vector, the result type is a vector of + // pointers. All vector operands must have the same number of elements. + if (VectorType *VT = dyn_cast(Op->getType())) { + GEPTy = VectorType::get(GEPTy, VT->getElementCount()); + break; + } + } // getelementptr poison, idx -> poison // getelementptr baseptr, poison -> poison 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 @@ -315,3 +315,32 @@ %gep = getelementptr inbounds i32, i32* %c1, i64 %ashr ret i32* %gep } + +define <8 x i32*> @gep_vector_index_op2_poison([144 x i32]* %ptr) { +; CHECK-LABEL: @gep_vector_index_op2_poison( +; CHECK-NEXT: ret <8 x i32*> poison +; + %res = getelementptr inbounds [144 x i32], [144 x i32]* %ptr, i64 0, <8 x i64> poison + ret <8 x i32*> %res +} + +%t.1 = type { i32, [144 x i32] } + +define <8 x i32*> @gep_vector_index_op3_poison(%t.1* %ptr) { +; CHECK-LABEL: @gep_vector_index_op3_poison( +; CHECK-NEXT: ret <8 x i32*> poison +; + %res = getelementptr inbounds %t.1, %t.1* %ptr, i64 0, i32 1, <8 x i64> poison + ret <8 x i32*> %res +} + +%t.2 = type { i32, i32 } +%t.3 = type { i32, [144 x %t.2 ] } + +define <8 x i32*> @gep_vector_index_op3_poison_constant_index_afterwards(%t.3* %ptr) { +; CHECK-LABEL: @gep_vector_index_op3_poison_constant_index_afterwards( +; CHECK-NEXT: ret <8 x i32*> poison +; + %res = getelementptr inbounds %t.3, %t.3* %ptr, i64 0, i32 1, <8 x i64> poison, i32 1 + ret <8 x i32*> %res +}