std::max_element, std::min_element and the hand-written argmax loop all
pair a min/max reduction with a second reduction tracking where the winner
was found. Neither vectorizes today: the index reduction reads the min/max
update's compare, which the reduction analysis rejects as a use outside the
chain.

Patch 1 recognizes the pair and vectorizes it. The epilogue reduces the
min/max accumulator, broadcasts it, masks every index lane that does not
hold that value to TYPE_MAX_VALUE, and takes a REDUC_MIN over the index
vector, so the first lane holding the min/max supplies the answer.

Patch 2 adds the library shape, where the index is the iterator itself and
so is pointer-typed. Querying REDUC_MIN against the pointer vectype gives
the wrong lane count, so the index is reduced over an unsigned surrogate of
the value's precision and the result pointer is rebuilt in the epilogue as
base + idx * stride.

Where the trip count type can outrun the surrogate the loop is versioned on
it; where it cannot, the guard would always hold and none is emitted.

Bootstrapped/regtested on AArch64 and x86-64.


Konstantinos Eleftheriou (2):
  vect: vectorize coupled min/max+index reductions [PR88259]
  vect: support the pointer-iterator argmax shape [PR88259]

 .../g++.dg/vect/vect-minmax-index.cc          |   68 ++
 .../gcc.dg/vect/vect-minmax-index-1.c         |  134 +++
 .../gcc.dg/vect/vect-minmax-index-2.c         |   57 +
 .../gcc.dg/vect/vect-minmax-index-3.c         |   46 +
 .../gcc.dg/vect/vect-minmax-index-4.c         |  219 ++++
 .../gcc.dg/vect/vect-minmax-index-5.c         |   49 +
 .../gcc.dg/vect/vect-minmax-index-6.c         |  101 ++
 .../gcc.dg/vect/vect-minmax-index-7.c         |  191 +++
 .../gcc.dg/vect/vect-minmax-index-8.c         |   84 ++
 .../aarch64/vect-minmax-index-epilogue.c      |   25 +
 .../aarch64/vect-minmax-index-sve.c           |   24 +
 gcc/tree-vect-loop.cc                         | 1044 ++++++++++++++++-
 gcc/tree-vect-patterns.cc                     |   12 +
 gcc/tree-vect-stmts.cc                        |  131 ++-
 gcc/tree-vectorizer.h                         |   41 +
 15 files changed, 2210 insertions(+), 16 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/vect/vect-minmax-index.cc
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-minmax-index-1.c
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-minmax-index-2.c
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-minmax-index-3.c
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-minmax-index-4.c
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-minmax-index-5.c
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-minmax-index-6.c
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-minmax-index-7.c
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-minmax-index-8.c
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/vect-minmax-index-epilogue.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/vect-minmax-index-sve.c

-- 
2.55.0

Reply via email to