On 8/19/2026 6:49 AM, [email protected] wrote:
From: Kyrylo Tkachov <[email protected]>

combine_simplify_rtx runs make_compound_operation over the address of a MEM
so that the shifts and masks combine has introduced are turned back into the
forms the target's address predicates recognize.  A PREFETCH holds an address
too, and aarch64 classifies it with the same routine it uses for a MEM, but
that address never gets the treatment, so a zero extend that combine has
rewritten as an AND with 0xffffffff is never rewritten back:

     Failed to match this instruction:
     (prefetch (plus:DI (and:DI (subreg:DI (reg:SI 108 [ i ]) 0)
                 (const_int 4294967295 [0xffffffff]))
             (reg/f:DI 107 [ b ]))
         (const_int 0 [0])
         (const_int 3 [0x3]))

On aarch64 the result is that __builtin_prefetch (b + i, 0, 3) with a 32-bit
i needs a separate address computation while a load of b[i] at the same
address does not:

     before                             after
        add     x1, x0, w1, uxtw        prfm    PLDL1KEEP, [x0, w1, uxtw]
        prfm    PLDL1KEEP, [x1]

Handle PREFETCH alongside MEM.

zstd 1.5.7 prefetches its match candidate through a 32-bit index in
ZSTD_RowFindBestMatch, which is 85% of the work at compression level 9.
Compressing the Silesia corpus on Grace with -mcpu=grace -O3, this saves
~1.65% dynamic instructions.

Bootstrapped and tested on aarch64-none-linux-gnu and x86_64-linux.
Ok for trunk?
Thanks,
Kyrill

gcc/ChangeLog:

        * combine.cc (combine_simplify_rtx): Handle PREFETCH like MEM when
        simplifying the address.

gcc/testsuite/ChangeLog:

        * gcc.target/aarch64/prefetch-extend-1.c: New test.
OK
jeff


Reply via email to