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

commit r17-4041-gb55ba08f1055d5c8748699a36f419c8078044594
Author: John David Anglin <[email protected]>
Date:   Wed Sep 9 13:25:24 2026 -0400

    hppa: Reduce r1 register pressure
    
    I have seen a few compiles fail where LRA is unable to find a
    register to spill.  If we don't need a spill, the best way to
    load the high part of a symbolic operand is to use the addil
    instruction.  It uses register r1 as its destinition operand.
    In the best case, the linker can remove unnecessary addil
    instructions.
    
    However, when there are multiple symbolic loads in a function,
    LRA is sometimes unable to find a register to spill.  The
    original reload was better at handling r1 register spills.
    
    This change adds an additional alternative using a ldil/addl
    sequence which avoids using the r1 register.  This is less
    costly than spilling r1.
    
    There is one PIC insn that I didn't update.  When PIC code is
    linked into non PIC executable, the linker needs to change the
    PIC register, r19, to the DP register, r27.  Currently, GNU ld
    only supports doing this with addil instructions.
    
    2026-09-09  John David Anglin  <[email protected]>
    
    gcc/ChangeLog:
    
            PR rtl-optimization/127142
            * config/pa/pa.md: Add alternatives using ldil/addl
            sequence to various insns to load the high part of
            a symbolic operand.

Diff:
---
 gcc/config/pa/pa.md | 54 +++++++++++++++++++++++++++++++++--------------------
 1 file changed, 34 insertions(+), 20 deletions(-)

diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 04a239806d26..4148d0dacf46 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -2701,6 +2701,9 @@
   [(set_attr "type" "multi")
    (set_attr "length" "16")])          ; 12 or 16
 
+;; DLTIND relocs need to be converted to DPREL relocs when PIC code
+;; isn't used in a shared object.  Currently, GNU ld only supports
+;; converting addil instructions.
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=a")
        (plus:SI (match_operand:SI 1 "register_operand" "r")
@@ -2713,16 +2716,18 @@
    (set_attr "length" "4")])
 
 (define_insn ""
-  [(set (match_operand:DI 0 "register_operand" "=a")
-       (plus:DI (match_operand:DI 1 "register_operand" "r")
+  [(set (match_operand:DI 0 "register_operand" "=a,!&r")
+       (plus:DI (match_operand:DI 1 "register_operand" "r,r")
                 (high:DI (match_operand 2 "" ""))))]
   "symbolic_operand (operands[2], Pmode)
    && ! function_label_operand (operands[2], Pmode)
    && TARGET_64BIT
    && flag_pic"
-  "addil LT'%G2,%1"
-  [(set_attr "type" "binary")
-   (set_attr "length" "4")])
+  "@
+   addil LT'%G2,%1
+   ldil LT'%G2,%0\;add,l %0,%1,%0"
+  [(set_attr "type" "binary,binary")
+   (set_attr "length" "4,8")])
 
 (define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=r")
@@ -2749,26 +2754,35 @@
 
 ;; Always use addil rather than ldil;add sequences.  This allows the
 ;; HP linker to eliminate the dp relocation if the symbolic operand
-;; lives in the TEXT space.
+;; lives in the TEXT space.  In order to avoid spill failures with
+;; LRA, we need ldil;add sequence with general register target.
 (define_insn ""
-  [(set (match_operand:SI 0 "register_operand" "=a")
+  [(set (match_operand:SI 0 "register_operand" "=a,!r")
        (high:SI (match_operand 1 "" "")))]
-  "symbolic_operand (operands[1], Pmode)
+  "! TARGET_LONG_LOAD_STORE
+   && symbolic_operand (operands[1], Pmode)
    && ! function_label_operand (operands[1], Pmode)
    && ! read_only_operand (operands[1], Pmode)
    && ! flag_pic"
-  "*
-{
-  if (TARGET_LONG_LOAD_STORE)
-    return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
-  else
-    return \"addil LR'%H1,%%r27\";
-}"
+  "@
+   addil LR'%H1,%%r27
+   ldil LR'%H1,%0\;{addl|add,l} %0,%%r27,%0"
+  [(set_attr "type" "binary,binary")
+   (set_attr "length" "4,8")])
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=a,!r")
+       (high:SI (match_operand 1 "" "")))]
+  "TARGET_LONG_LOAD_STORE
+   && symbolic_operand (operands[1], Pmode)
+   && ! function_label_operand (operands[1], Pmode)
+   && ! read_only_operand (operands[1], Pmode)
+   && ! flag_pic"
+  "@
+   addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1
+   ldil NLR'%H1,%0\;{addl|add,l} %0,%%r27,%0\;ldo N'%H1(%0),%0"
   [(set_attr "type" "binary")
-   (set (attr "length")
-      (if_then_else (not (match_test "TARGET_LONG_LOAD_STORE"))
-                   (const_int 4)
-                   (const_int 8)))])
+   (set_attr "length" "8,12")])
 
 
 ;; This is for use in the prologue/epilogue code.  We need it
@@ -2794,7 +2808,7 @@
   "reload_completed && TARGET_64BIT"
   "@
    addil L'%G2,%1
-   ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
+   ldil L'%G2,%0\;add,l %0,%1,%0"
   [(set_attr "type" "binary,binary")
    (set_attr "length" "4,8")])

Reply via email to