LRA, rs6000, Darwin: Revise lo_sum use for forced constants [PR104117].
authorIain Sandoe <iain@sandoe.co.uk>
Wed, 23 Feb 2022 13:53:44 +0000 (13:53 +0000)
committerIain Sandoe <iain@sandoe.co.uk>
Fri, 4 Mar 2022 15:06:25 +0000 (15:06 +0000)
Follow up discussion to the initial patch for this PR identified that it is
preferable to avoid the LRA change, and arrange for the target to reject the
hi and lo_sum selections when presented with an invalid address.

We split the Darwin high/low selectors into two:
 1. One that handles non-PIC addresses (kernel mode, mdynamic-no-pic).
 2. One that handles PIC addresses and rejects SYMBOL_REFs unless they are
    suitably wrapped in the MACHOPIC_OFFSET unspec.

The second case is handled by providing a new predicate (macho_pic_address)
that checks the requirements.

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
PR target/104117

gcc/ChangeLog:

* config/rs6000/darwin.md (@machopic_high_<mode>): New.
(@machopic_low_<mode>): New.
* config/rs6000/predicates.md (macho_pic_address): New.
* config/rs6000/rs6000.cc (rs6000_legitimize_address): Do not
apply the TLS processing to Darwin.
* lra-constraints.cc (process_address_1): Revert the changes
in r12-7209.

gcc/config/rs6000/darwin.md
gcc/config/rs6000/predicates.md
gcc/config/rs6000/rs6000.cc
gcc/lra-constraints.cc

index 8443585..e73d59e 100644 (file)
@@ -121,21 +121,32 @@ You should have received a copy of the GNU General Public License
    stw %0,lo16(%2)(%1)"
   [(set_attr "type" "store")])
 
-;; 64-bit MachO load/store support
-
 ;; Mach-O PIC.
 
 (define_insn "@macho_high_<mode>"
   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
        (high:P (match_operand 1 "" "")))]
-  "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN)"
+  "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && !flag_pic"
   "lis %0,ha16(%1)")
 
 (define_insn "@macho_low_<mode>"
   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
        (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
                   (match_operand 2 "" "")))]
-   "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN)"
+   "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && !flag_pic"
+   "la %0,lo16(%2)(%1)")
+
+(define_insn "@machopic_high_<mode>"
+  [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
+       (high:P (match_operand 1 "macho_pic_address" "")))]
+  "TARGET_MACHO && flag_pic"
+  "lis %0,ha16(%1)")
+
+(define_insn "@machopic_low_<mode>"
+  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+       (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
+                  (match_operand 2 "macho_pic_address" "")))]
+   "TARGET_MACHO && flag_pic"
    "la %0,lo16(%2)(%1)")
 
 (define_split
index c65dfb9..28f6e98 100644 (file)
  (if_then_else (match_test "TARGET_VSX")
   (match_operand 0 "reg_or_cint_operand")
   (match_operand 0 "const_int_operand")))
+
+;; Return true if the operand is a valid Mach-O pic address.
+;;
+(define_predicate "macho_pic_address"
+  (match_code "const,unspec")
+{
+  if (GET_CODE (op) == CONST)
+    op = XEXP (op, 0);
+
+  if (GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_MACHOPIC_OFFSET)
+    return CONSTANT_P (XVECEXP (op, 0, 0));
+  else
+    return false;
+})
index 5b100a8..2388d44 100644 (file)
@@ -9021,7 +9021,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
       else
        return force_reg (Pmode, x);
     }
-  if (SYMBOL_REF_P (x))
+  if (SYMBOL_REF_P (x) && !TARGET_MACHO)
     {
       enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
       if (model != 0)
index 5cd89e7..080b44a 100644 (file)
@@ -3625,8 +3625,21 @@ process_address_1 (int nop, bool check_only_p,
                  *ad.inner = gen_rtx_LO_SUM (Pmode, new_reg, addr);
                  if (!valid_address_p (op, &ad, cn))
                    {
-                     *ad.inner = addr; /* Punt.  */
-                     code = -1;
+                     /* Try to put lo_sum into register.  */
+                     insn = emit_insn (gen_rtx_SET
+                                       (new_reg,
+                                        gen_rtx_LO_SUM (Pmode, new_reg, addr)));
+                     code = recog_memoized (insn);
+                     if (code >= 0)
+                       {
+                         *ad.inner = new_reg;
+                         if (!valid_address_p (op, &ad, cn))
+                           {
+                             *ad.inner = addr;
+                             code = -1;
+                           }
+                       }
+
                    }
                }
              if (code < 0)