https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126142

            Bug ID: 126142
           Summary: Missed vectorization: std::max_element-style
                    pointer-iterator argmax loops stay scalar (no integer
                    index in the IR)
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ptomsich at gcc dot gnu.org
  Target Milestone: ---

The pointer-iterator form of an argmax loop, as instantiated by
std::max_element/std::min_element, does not vectorize:

  const float *
  maxel (const float *first, const float *last)
  {
    const float *result = first;
    while (++first != last)
      if (*result < *first)
        result = first;
    return result;
  }

Compile with -O3 on aarch64-linux (also reproduces on x86_64); observed on
trunk 20260705 (g:3b443e76414).  The loop remains a scalar compare-and-select
chain.

This is one of the two dominant scalar kernels in the beam-search/nbest phase
of the marian NMT decoder (SPEC CPU 2026, 772.marian_r).

The cached best value (PRE has turned *result into a carried scalar,
prephitmp_10) fails reduction classification with the same message as PR88259:

  maxel.c:5:18: note:   Analyze phi: prephitmp_10 = PHI <prephitmp_3(8),
pretmp_9(18)>
  maxel.c:5:18: missed:   reduction used in loop.
  maxel.c:5:18: missed:   Unknown def-use cycle pattern.

The pointer cycle itself is recognized as a reduction:

  maxel.c:5:18: note:   Analyze phi: result_13 = PHI <result_4(8),
first_5(D)(18)>
  maxel.c:5:18: note:   reduction path: result_4 result_13
  maxel.c:5:18: note:   Detected reduction.

However, the compare feeding the select uses the value from the "unknown"
cycle:

  maxel.c:5:18: note:   vect_is_simple_use: operand prephitmp_10 = PHI <...>,
type of def: unknown
  maxel.c:5:18: missed:   Unsupported pattern.
  maxel.c:6:8: missed:   not vectorized: unsupported use in stmt.
  maxel.c:5:18: note:  ***** Analysis failed with vector mode V4SF
  maxel.c:5:18: missed: couldn't vectorize loop


This is after if-conversion.
phiopt defers the conditional-move and ifcvt forms the COND_EXPRs; but the
reduction is not recognized.

What we propose (implementation exists; to be submitted as a follow-up series
to the PR88259 patches):
- a pre-vectorizer lowering that recognizes this shape (introduce a parallel
integer IV, track best-value and best-index as scalar reductions)
- materialize the winning pointer from the base pointer and best index at the
loop exit

Together with the PR88259 vectorizer support, this closes the dominant scalar
hotspot in 772.marian_r for us (approximately 13% end-to-end on an AArch64
server, measured against the same trunk revision).
The PR88259 fix and this lowering are both necessary to optimise marian.

Reply via email to