diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -347,6 +347,14 @@ ElementCount EC = EI.getVectorOperandType()->getElementCount(); unsigned NumElts = EC.getKnownMinValue(); + // 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(SrcVec)) + if (isSplatValue(SE) && IndexC->getValue().ult(NumElts)) + if (auto *IE = dyn_cast(SE->getOperand(0))) + return replaceInstUsesWith(EI, IE->getOperand(1)); + // InstSimplify should handle cases where the index is invalid. // For fixed-length vector, it's invalid to extract out-of-range element. if (!EC.isScalable() && IndexC->getValue().uge(NumElts)) 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