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 @@ -4495,9 +4495,13 @@ // find a previously computed scalar that was inserted into the vector. if (auto *IdxC = dyn_cast(Idx)) { // For fixed-length vector, fold into undef if index is out of bounds. - if (isa(VecVTy) && - IdxC->getValue().uge(cast(VecVTy)->getNumElements())) + unsigned MinNumElts = VecVTy->getElementCount().getKnownMinValue(); + if (isa(VecVTy) && IdxC->getValue().uge(MinNumElts)) return PoisonValue::get(VecVTy->getElementType()); + // Handle case where an element is extracted from a splat. + if (IdxC->getValue().ult(MinNumElts)) + if (auto *Splat = getSplatValue(Vec)) + return Splat; if (Value *Elt = findScalarElement(Vec, IdxC->getZExtValue())) return Elt; } diff --git a/llvm/test/Transforms/InstCombine/gep-vector-indices.ll b/llvm/test/Transforms/InstCombine/gep-vector-indices.ll --- a/llvm/test/Transforms/InstCombine/gep-vector-indices.ll +++ b/llvm/test/Transforms/InstCombine/gep-vector-indices.ll @@ -61,10 +61,7 @@ define i32* @vector_splat_ptrs_nxv2i64_ext0(i32* %a, i64 %index) { ; CHECK-LABEL: @vector_splat_ptrs_nxv2i64_ext0( -; CHECK-NEXT: [[TMP:%.*]] = insertelement poison, i32* [[A:%.*]], i32 0 -; CHECK-NEXT: [[SPLATOFA:%.*]] = shufflevector [[TMP]], poison, zeroinitializer -; CHECK-NEXT: [[TMP0:%.*]] = extractelement [[SPLATOFA]], i32 0 -; CHECK-NEXT: [[RES:%.*]] = getelementptr i32, i32* [[TMP0]], i64 [[INDEX:%.*]] +; CHECK-NEXT: [[RES:%.*]] = getelementptr i32, i32* [[A:%.*]], i64 [[INDEX:%.*]] ; CHECK-NEXT: ret i32* [[RES]] ; %tmp = insertelement poison, i32* %a, i32 0 diff --git a/llvm/test/Transforms/InstCombine/vscale_extractelement-inseltpoison.ll b/llvm/test/Transforms/InstCombine/vscale_extractelement-inseltpoison.ll --- a/llvm/test/Transforms/InstCombine/vscale_extractelement-inseltpoison.ll +++ b/llvm/test/Transforms/InstCombine/vscale_extractelement-inseltpoison.ll @@ -55,13 +55,9 @@ ret i8 %r } -; TODO: Instcombine could optimize to return %v. define i32 @extractelement_shuffle_in_range(i32 %v) { ; CHECK-LABEL: @extractelement_shuffle_in_range( -; CHECK-NEXT: [[IN:%.*]] = insertelement poison, i32 [[V:%.*]], i32 0 -; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector [[IN]], poison, zeroinitializer -; CHECK-NEXT: [[R:%.*]] = extractelement [[SPLAT]], i32 1 -; CHECK-NEXT: ret i32 [[R]] +; CHECK-NEXT: ret i32 %v ; %in = insertelement poison, i32 %v, i32 0 %splat = shufflevector %in, poison, zeroinitializer diff --git a/llvm/test/Transforms/InstCombine/vscale_extractelement.ll b/llvm/test/Transforms/InstCombine/vscale_extractelement.ll --- a/llvm/test/Transforms/InstCombine/vscale_extractelement.ll +++ b/llvm/test/Transforms/InstCombine/vscale_extractelement.ll @@ -55,13 +55,9 @@ ret i8 %r } -; TODO: Instcombine could optimize to return %v. define i32 @extractelement_shuffle_in_range(i32 %v) { ; CHECK-LABEL: @extractelement_shuffle_in_range( -; CHECK-NEXT: [[IN:%.*]] = insertelement undef, i32 [[V:%.*]], i32 0 -; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector [[IN]], undef, zeroinitializer -; CHECK-NEXT: [[R:%.*]] = extractelement [[SPLAT]], i32 1 -; CHECK-NEXT: ret i32 [[R]] +; CHECK-NEXT: ret i32 %v ; %in = insertelement undef, i32 %v, i32 0 %splat = shufflevector %in, undef, zeroinitializer