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,17 @@ // 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 NumElts = + cast(VecVTy)->getElementCount().getKnownMinValue(); + if (isa(VecVTy) && IdxC->getValue().uge(NumElts)) return PoisonValue::get(VecVTy->getElementType()); + // It handle cases where splat is the operand of the extract + // extractelement (shufflevector (insertelement lane, 0), 0), idx) + // It returns the lane value from insert + if (auto *SE = dyn_cast(Vec)) + if (isSplatValue(SE) && IdxC->getValue().ult(NumElts)) + if (auto *IE = dyn_cast(SE->getOperand(0))) + return IE->getOperand(1); 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