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

            Bug ID: 126376
           Summary: aarch64: cunrolli unrolls small constant-trip inner
                    loops and blocks dot-product vectorization
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: konstantinos.eleftheriou at vrull dot eu
  Target Milestone: ---
            Target: aarch64-*-*

Created attachment 65118
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65118&action=edit
reduced_testcase

The inner loop of a widening multiply-accumulate nest gets fully
unrolled by cunrolli before the vectorizer runs. Once it is
straight-line code there is no loop left for vect_recog_dot_prod_pattern
to match, so the vectorizer falls back to element-wise SLP on the outer
body: widening multiplies and uzp1/uzp2 shuffles instead of a dot
product.

For the attached testcase with `-O3 -mcpu=ampere1a -S reduced_testcase.c`
we get 466 lines of assembly, 144 uzp1/uzp2 instructions and no usdot.
The inner loop is already gone by the time the vectorizer runs.

Using `#pragma GCC unroll 0` for the inner loop fixes this. A usdot is emitted,
no uzp instructions and the assembly goes down to 39 lines.

The testcase is extracted from SPEC2026's 706.stockfish_r benchmark.

Suggested fix:

A small pass that runs just before cunrolli, spots these dot-product-shaped
inner loops and marks them so cunrolli leaves them alone. The loop then
reaches the vectorizer intact and the existing DOT_PROD recognizer takes it
from there.

Reply via email to