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
