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 @@ -4489,9 +4489,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()); + // It handle cases where splat is the operand of the extract + 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/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