https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126143
Bug ID: 126143
Summary: phiopt does not flatten predicate-uniform multi-PHI
diamonds: argmax-style scalar loops keep unpredictable
branches at -O2
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: ---
When a single condition controls updates to several variable, the resulting
multi-PHI diamond survives the whole GIMPLE pipeline as control flow:
int
argmax (const float *a, int n)
{
float best = a[0];
int bi = 0;
for (int i = 1; i < n; i++)
if (a[i] > best)
{
best = a[i];
bi = i;
}
return bi;
}
At -O2 on aarch64-linux (trunk 20260705, g:3b443e76414) the loop body compiles
to a compare and a conditional branch:
fcmpe s31, s30
b.gt ... // data-dependent; mispredicts on random input
while the flattened form is branchless:
fcmpe s30, s31
fcsel s31, s30, s31, gt
fcmpe s30, s29
csel w0, w2, w0, gt
This affects the the nbest phase of the marian NMT decoder in SPEC CPU 2026
772.marian_r.
We propose (implementation exists, to be submitted): a phiopt extension that
flattens predicate-uniform PHI clusters into straight-line code. We rewrite
each PHI as a COND_EXPR (folding to MIN/MAX_EXPR where possible with a small
match.pd change).
With gating on late phiopt only, and only when the cluster feeds loop-carried
reductions (to avoid regressions on brnaches that profile well), we checked
against SPEC-wide regressions on Aarch64.
Impact: in combination (we only measured in combination, sorry...) with coupled
min/max+index vectorization (PR88259) it additionally contributes about 2%
end-to-end on 772.marian_r on an AArch64 server core.