https://gcc.gnu.org/g:81c47986e1d8efa70a4bd28e8dfc62bfca8e8362

commit r15-3307-g81c47986e1d8efa70a4bd28e8dfc62bfca8e8362
Author: John David Anglin <dang...@gcc.gnu.org>
Date:   Thu Aug 29 11:53:45 2024 -0400

    hppa: Fix handling of unscaled index addresses on HP-UX
    
    The PA-RISC architecture uses the top two bits of memory pointers
    to select space registers.  The space register ID is ored with the
    pointer offset to compute the global virtual address for an access.
    
    The new late combine passes broke gcc on HP-UX.  One of these passes
    runs after reload.  The existing code assumed no unscaled index
    instructions would be created after reload as the REG_POINTER flag
    is not reliable after reload.  The new pass sometimes interchanged
    the base and index registers, causing these instructions to fault
    when the wrong space register was selected.
    
    I investigated various alternatives to try to retain generation
    of unscaled index instructions on HP-UX.  It's not possible to
    simply treat unscaled index addresses as not legitimate after
    reload as sometimes instructions need to be rerecognized after
    reload.  So, we needed to allow unscaled index addresses after
    reload and to disable the late combine passes.
    
    I had noticed that reversing the current order of base and index
    register canonicalization resulted in more accesses using unscaled
    index addresses.  However, this exposed issues with the REG_POINTER
    flag.
    
    The flag is not propagated when a constant is added to a pointer.
    Tree opimization sometimes adds two pointers.  I found that I had
    to treat the result as a pointer but the addition generally corrupts
    the space register bits.  These get fixed when a negative pointer
    is added.  Finally, the REG_POINTER flag isn't set when a pointer
    is passed in a function call.  I couldn't get this approach to work.
    
    Thus, I came to the conclusion that the best approach was to
    disable use of unscaled index addresses on HP-UX.  I don't think
    this impacts performance significantly.  Code size might get
    slightly larger but we get some or more back from having the late
    combine passes.
    
    2024-08-29  John David Anglin  <dang...@gcc.gnu.org>
    
    gcc/ChangeLog:
    
            * config/pa/pa.cc (load_reg): Don't generate load with
            unscaled index address when !TARGET_NO_SPACE_REGS.
            (pa_legitimate_address_p): Only allow unscaled index
            addresses when TARGET_NO_SPACE_REGS.

Diff:
---
 gcc/config/pa/pa.cc | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/gcc/config/pa/pa.cc b/gcc/config/pa/pa.cc
index 911b7d96e9b6..297ec3a6f69b 100644
--- a/gcc/config/pa/pa.cc
+++ b/gcc/config/pa/pa.cc
@@ -4517,7 +4517,7 @@ load_reg (int reg, HOST_WIDE_INT disp, int base)
       rtx tmpreg = gen_rtx_REG (Pmode, 1);
 
       emit_move_insn (tmpreg, delta);
-      if (TARGET_DISABLE_INDEXING)
+      if (!TARGET_NO_SPACE_REGS || TARGET_DISABLE_INDEXING)
        {
          emit_move_insn (tmpreg, gen_rtx_PLUS (Pmode, tmpreg, basereg));
          src = gen_rtx_MEM (word_mode, tmpreg);
@@ -11009,17 +11009,13 @@ pa_legitimate_address_p (machine_mode mode, rtx x, 
bool strict, code_helper)
        }
 
       if (!TARGET_DISABLE_INDEXING
-         /* Only accept the "canonical" INDEX+BASE operand order
-            on targets with non-equivalent space registers.  */
-         && (TARGET_NO_SPACE_REGS
-             ? REG_P (index)
-             : (base == XEXP (x, 1) && REG_P (index)
-                && (reload_completed
-                    || (reload_in_progress && HARD_REGISTER_P (base))
-                    || REG_POINTER (base))
-                && (reload_completed
-                    || (reload_in_progress && HARD_REGISTER_P (index))
-                    || !REG_POINTER (index))))
+         /* 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
+         && REG_P (index)
          && MODE_OK_FOR_UNSCALED_INDEXING_P (mode)
          && (strict ? STRICT_REG_OK_FOR_INDEX_P (index)
                     : REG_OK_FOR_INDEX_P (index))

Reply via email to