diff options
author | Kerry McLaughlin <kerry.mclaughlin@arm.com> | 2025-08-01 09:54:43 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-01 09:54:43 +0100 |
commit | e1706763515dcd50edf67a377386bc6f1e33a6d0 (patch) | |
tree | b057efb4dd5a9f959231d921185212584b43657c | |
parent | b0313adefa2dd7b40ad3cf48c926045806af5a5f (diff) | |
download | llvm-e1706763515dcd50edf67a377386bc6f1e33a6d0.zip llvm-e1706763515dcd50edf67a377386bc6f1e33a6d0.tar.gz llvm-e1706763515dcd50edf67a377386bc6f1e33a6d0.tar.bz2 |
[Instcombine] Combine extractelement from a vector_extract at index 0 (#151491)
Extracting any element from a subvector starting at index 0 is
equivalent to extracting from the original vector, i.e.
extract_elt(vector_extract(x, 0), y) -> extract_elt(x, y)
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp | 7 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/scalable-extract-subvec-elt.ll | 36 |
2 files changed, 43 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp index 00b877b..fe0f308 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -462,6 +462,13 @@ Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) { return ScalarPHI; } + // If SrcVec is a subvector starting at index 0, extract from the + // wider source vector + Value *V; + if (match(SrcVec, + m_Intrinsic<Intrinsic::vector_extract>(m_Value(V), m_Zero()))) + return ExtractElementInst::Create(V, Index); + // TODO come up with a n-ary matcher that subsumes both unary and // binary matchers. UnaryOperator *UO; diff --git a/llvm/test/Transforms/InstCombine/scalable-extract-subvec-elt.ll b/llvm/test/Transforms/InstCombine/scalable-extract-subvec-elt.ll new file mode 100644 index 0000000..1e089e1 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/scalable-extract-subvec-elt.ll @@ -0,0 +1,36 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt -S -passes=instcombine < %s | FileCheck %s + +define i1 @extract_const_idx(<vscale x 4 x i1> %a) { +; CHECK-LABEL: define i1 @extract_const_idx( +; CHECK-SAME: <vscale x 4 x i1> [[A:%.*]]) { +; CHECK-NEXT: [[ELT:%.*]] = extractelement <vscale x 4 x i1> [[A]], i64 1 +; CHECK-NEXT: ret i1 [[ELT]] +; + %subvec = call <vscale x 2 x i1> @llvm.vector.extract.nxv2i1.nxv4i1.i64(<vscale x 4 x i1> %a, i64 0) + %elt = extractelement <vscale x 2 x i1> %subvec, i32 1 + ret i1 %elt +} + +define float @extract_variable_idx(<vscale x 4 x float> %a, i32 %idx) { +; CHECK-LABEL: define float @extract_variable_idx( +; CHECK-SAME: <vscale x 4 x float> [[A:%.*]], i32 [[IDX:%.*]]) { +; CHECK-NEXT: [[ELT:%.*]] = extractelement <vscale x 4 x float> [[A]], i32 [[IDX]] +; CHECK-NEXT: ret float [[ELT]] +; + %subvec = call <vscale x 2 x float> @llvm.vector.extract.nxv2f32.nxv4f32.i64(<vscale x 4 x float> %a, i64 0) + %elt = extractelement <vscale x 2 x float> %subvec, i32 %idx + ret float %elt +} + +define float @negative_test(<vscale x 4 x float> %a) { +; CHECK-LABEL: define float @negative_test( +; CHECK-SAME: <vscale x 4 x float> [[A:%.*]]) { +; CHECK-NEXT: [[SUBVEC:%.*]] = call <vscale x 2 x float> @llvm.vector.extract.nxv2f32.nxv4f32(<vscale x 4 x float> [[A]], i64 2) +; CHECK-NEXT: [[ELT:%.*]] = extractelement <vscale x 2 x float> [[SUBVEC]], i64 1 +; CHECK-NEXT: ret float [[ELT]] +; + %subvec = call <vscale x 2 x float> @llvm.vector.extract.nxv2f32.nxv4f32.i64(<vscale x 4 x float> %a, i64 2) + %elt = extractelement <vscale x 2 x float> %subvec, i32 1 + ret float %elt +} |