https://gcc.gnu.org/g:ecac1841e6828fb8999c1becbc52798133dd2c17

commit r16-5533-gecac1841e6828fb8999c1becbc52798133dd2c17
Author: John David Anglin <[email protected]>
Date:   Sun Nov 23 17:27:51 2025 -0500

    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:
---
 gcc/config/pa/pa.cc         | 35 +++++++++++++++++++++++------------
 gcc/config/pa/predicates.md | 20 --------------------
 2 files changed, 23 insertions(+), 32 deletions(-)

diff --git a/gcc/config/pa/pa.cc b/gcc/config/pa/pa.cc
index b63ccf1982f2..40abe07ced13 100644
--- a/gcc/config/pa/pa.cc
+++ b/gcc/config/pa/pa.cc
@@ -5764,11 +5764,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 +11012,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 +11029,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 b0f8274ff798..ecd2f255c9c7 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)));
 })

Reply via email to