Tested on hppa64-hp-hpux11.11.  Committed to trunk.

Dave
---

hppa: Fix scaled and unscaled index support on targets with non-equivalent 
space registers

HP-UX targets have non-equivalent space registers.  The base register
in most loads and stores selects the space register used to calculate
the global virtual address for the instruction.

Previously, the PA-RISC backend attempted to canonicalize the
register order in INDEX + BASE register addresses.  This has always
been problematic as reload would sometimes lose the REG_POINTER
flag used to mark a base register.  As a result, we allowed any
register order after reload and prayed the registers would be
in canonical order.

This broke with the new late_combine2 pass.  It sometimes creates
new indexed instructions after reload.  pa_legitimate_address_p
needs updating to ensure the base register is marked with the
REG_POINTER flag and the index register is not marked.

If scaled index instructions are created before reload, the LRA
pass will sometimes convert it an unscaled index instruction
plus reloads and drop the REG_POINTER flag that was in the base
register.  Thus, we can't allow scaled and unscaled index loads
and stores until reload is completed.

2025-11-23  John David Anglin  <[email protected]>

gcc/ChangeLog:

        * config/pa/pa.cc (pa_print_operand): Use REG_POINTER
        flag to select base and index registers on targets with
        non-equivalent space registers.
        (pa_legitimate_address_p): Don't allow scaled and unscaled
        indexed addresses until reload is complete.  Allow any
        register order in unscaled addresses as long as the
        REG_POINTER flag is correctly set/unset in the base/index
        registers.
        * config/pa/predicates.md (mem_operand): Remove code to
        delay creating move insns with unscaled indexed addresses
        until CSE is not expected.
        (move_src_operand): Likewise.

diff --git a/gcc/config/pa/pa.cc b/gcc/config/pa/pa.cc
index b63ccf1982f..c3f38449b18 100644
--- a/gcc/config/pa/pa.cc
+++ b/gcc/config/pa/pa.cc
@@ -5764,11 +5768,22 @@ pa_print_operand (FILE *file, rtx x, int code)
                   && GET_CODE (XEXP (XEXP (x, 0), 1)) == REG)
            {
              /* Because the REG_POINTER flag can get lost during reload,
-                pa_legitimate_address_p canonicalizes the order of the
-                index and base registers in the combined move patterns.  */
+                we now defer creation of instructions with scaled and
+                unscaled index addresses until after reload.  We require
+                that the flag be set in the base register on targets
+                that use space registers.  */
              rtx base = XEXP (XEXP (x, 0), 1);
              rtx index = XEXP (XEXP (x, 0), 0);
 
+             /* Accept non-canonical register order.  */
+             if (!TARGET_NO_SPACE_REGS && !REG_POINTER (base))
+               {
+                 rtx tmp = base;
+                 base = index;
+                 index = tmp;
+                 gcc_assert (REG_POINTER (base));
+               }
+
              fprintf (file, "%s(%s)",
                       reg_names [REGNO (index)], reg_names [REGNO (base)]);
            }
@@ -11001,12 +11016,15 @@ pa_legitimate_address_p (machine_mode mode, rtx x, 
bool strict, code_helper)
 
       if (!TARGET_DISABLE_INDEXING
          /* Currently, the REG_POINTER flag is not set in a variety
-            of situations (e.g., call arguments and pointer arithmetic).
-            As a result, we can't reliably determine when unscaled
-            addresses are legitimate on targets that need space register
-            selection.  */
-         && TARGET_NO_SPACE_REGS
+            of situations (e.g., call arguments and pointer arithmetic)
+            and the flag can be lost during reload.  So, we only allow
+            unscaled index addresses after reload.  We can accept either
+            register order.  */
          && REG_P (index)
+         && (TARGET_NO_SPACE_REGS
+             || (reload_completed
+                 && ((REG_POINTER (base) && !REG_POINTER (index))
+                     || (!REG_POINTER (base) && REG_POINTER (index)))))
          && MODE_OK_FOR_UNSCALED_INDEXING_P (mode)
          && (strict ? STRICT_REG_OK_FOR_INDEX_P (index)
                     : REG_OK_FOR_INDEX_P (index))
@@ -11015,13 +11033,10 @@ pa_legitimate_address_p (machine_mode mode, rtx x, 
bool strict, code_helper)
        return true;
 
       if (!TARGET_DISABLE_INDEXING
-         /* Only accept base operands with the REG_POINTER flag prior to
+         /* Only accept base operands with the REG_POINTER flag after
             reload on targets with non-equivalent space registers.  */
          && (TARGET_NO_SPACE_REGS
-             || reload_completed
-             || ((lra_in_progress || reload_in_progress)
-                  && HARD_REGISTER_P (base))
-             || REG_POINTER (base))
+             || (reload_completed && REG_POINTER (base)))
          && GET_CODE (index) == MULT
          && REG_P (XEXP (index, 0))
          && GET_MODE (XEXP (index, 0)) == Pmode
diff --git a/gcc/config/pa/predicates.md b/gcc/config/pa/predicates.md
index b0f8274ff79..ecd2f255c9c 100644
--- a/gcc/config/pa/predicates.md
+++ b/gcc/config/pa/predicates.md
@@ -472,16 +472,6 @@
   if (! MEM_P (op))
     return false;
 
-  /* Until problems with management of the REG_POINTER flag are resolved,
-     we need to delay creating move insns with unscaled indexed addresses
-     until CSE is not expected.  */
-  if (!TARGET_NO_SPACE_REGS
-      && !cse_not_expected
-      && GET_CODE (XEXP (op, 0)) == PLUS
-      && REG_P (XEXP (XEXP (op, 0), 0))
-      && REG_P (XEXP (XEXP (op, 0), 1)))
-    return false;
-
   return memory_address_p (mode, XEXP (op, 0));
 })
 
@@ -496,16 +486,6 @@
   if (! MEM_P (op))
     return false;
 
-  /* Until problems with management of the REG_POINTER flag are resolved,
-     we need to delay creating move insns with unscaled indexed addresses
-     until CSE is not expected.  */
-  if (!TARGET_NO_SPACE_REGS
-      && !cse_not_expected
-      && GET_CODE (XEXP (op, 0)) == PLUS
-      && REG_P (XEXP (XEXP (op, 0), 0))
-      && REG_P (XEXP (XEXP (op, 0), 1)))
-    return false;
-
   return (memory_address_p (mode, XEXP (op, 0)));
 })
 

Attachment: signature.asc
Description: PGP signature

Reply via email to