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
