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.