On 8/25/26 8:03 AM, [email protected] wrote:
From: Kyrylo Tkachov <[email protected]>

Combine can form a prefetch address that contains a power-of-two MULT.
This is valid in an address context.  The AArch64 predicate accepts it
during non-strict recognition.  Strict checking can then require LRA to
move the complete address to a register.

The reload_inner_addr path passed the address directly to lra_emit_move.
This moved the address-canonical MULT into a normal SET:

     (set (reg:DI 115)
          (and:DI (mult:DI (subreg:DI ...)
                           (const_int 8))
                  (const_int 34359738360)))

Outside an address, ASHIFT is the canonical form.  The generated SET did
not match an instruction and LRA failed in lra_set_insn_recog_data.

Call the existing canonicalize_reload_addr helper before the move.  It
changes the relevant part of the source to:

     (ashift:DI (subreg:DI ...) (const_int 3))

The existing add pattern then recognizes the complete address reload.  Add
a test for signed and unsigned scaled prefetch indices.

Bootstrapped and regression tested on aarch64-unknown-linux-gnu.
Ok for trunk?


Yes.  Thank you, Kyrill, for fixing this.

gcc/ChangeLog:

        PR rtl-optimization/127056
        * lra-constraints.cc (process_address_1): Canonicalize a complete
        address reload.

gcc/testsuite/ChangeLog:

        PR rtl-optimization/127056
        * gcc.target/aarch64/pr127056.c: New test.

Signed-off-by: Kyrylo Tkachov <[email protected]>
---
  gcc/lra-constraints.cc                      |  2 +-
  gcc/testsuite/gcc.target/aarch64/pr127056.c | 19 +++++++++++++++++++
  2 files changed, 20 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/gcc.target/aarch64/pr127056.c

diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 2d95758a5b7..153624b8859 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -4418,7 +4418,7 @@ process_address_1 (int nop, bool check_only_p,
        addr = *ad.inner;
        new_reg = lra_create_new_reg (Pmode, NULL_RTX, cl, NULL, "addr");
        /* addr => new_base.  */
-      lra_emit_move (new_reg, addr);
+      lra_emit_move (new_reg, canonicalize_reload_addr (addr));
        *ad.inner = new_reg;
      }
    *before = end_sequence ();
diff --git a/gcc/testsuite/gcc.target/aarch64/pr127056.c 
b/gcc/testsuite/gcc.target/aarch64/pr127056.c
new file mode 100644
index 00000000000..9218fac5bc9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr127056.c
@@ -0,0 +1,19 @@
+/* PR rtl-optimization/127056 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+char (*a)[8];
+int b;
+
+void
+c (void)
+{
+  if (b >= 0)
+    __builtin_prefetch (a[b]);
+}
+
+void
+d (char (*p)[8], unsigned int i)
+{
+  __builtin_prefetch (p[i]);
+}

Reply via email to