This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix PR target/7784 (Sparc)


> I'd really prefer that we fix reload.  It's *supposed* to handle
> this.  LEGITIMIZE_RELOAD_ADDRESS should only be needed for
> optmization, not correctness.

You're right, the infrastructure is already in place, it simply doesn't 
trigger because of a too restrictive condition.

One of the cases in find_reloads_address() contains this comment:

     Handle all base registers here, not just fp/ap/sp, because on some
     targets (namely SH) we can also get too large displacements from
     big-endian corrections.  */


We have the exact same situation on Sparc for the two cases following the 
previous one: find_reloads_toplev() produces the invalid offsetted address 
because of

      /* If the subreg contains a reg that will be converted to a mem,
	 convert the subreg to a narrower memref now.
	 Otherwise, we would get (subreg (mem ...) ...),
	 which would force reload of the mem.

	 We also need to do this if there is an equivalent MEM that is
	 not offsettable.  In that case, alter_subreg would produce an
	 invalid address on big-endian machines.

so we need to handle all base registers, not just fp/ap/sp, in the two 
aforementioned cases.

Does the patch look ok? If so, on which branch(es) do you want me to test it?

-- 
Eric Botcazou


2003-03-23  Eric Botcazou  <ebotcazou at libertysurf dot fr>

        PR target/7784
	* reload.c (find_reloads_address):  Handle
	(PLUS (PLUS (REG) (REG)) (CONST_INT)) form for
	all base registers.
Index: reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.178.2.4.2.4
diff -u -p -r1.178.2.4.2.4 reload.c
--- reload.c	24 Oct 2002 08:59:49 -0000	1.178.2.4.2.4
+++ reload.c	23 Mar 2003 08:40:38 -0000
@@ -4825,25 +4825,23 @@ find_reloads_address (mode, memrefloc, a
      that the index needs a reload and find_reloads_address_1 will take care
      of it.
 
-     If we decide to do something here, it must be that
-     `double_reg_address_ok' is true and that this address rtl was made by
-     eliminate_regs.  We generate a reload of the fp/sp/ap + constant and
+     Handle all base registers here, not just fp/ap/sp, because on some
+     targets (namely Sparc) we can also get invalid addresses from preventive
+     subreg big-endian corrections made by find_reloads_toplev.
+
+     If we decide to do something, it must be that `double_reg_address_ok'
+     is true.  We generate a reload of the base register + constant and
      rework the sum so that the reload register will be added to the index.
      This is safe because we know the address isn't shared.
 
-     We check for fp/ap/sp as both the first and second operand of the
-     innermost PLUS.  */
+     We check for the base register as both the first and second operand of
+     the innermost PLUS.  */
 
   else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
 	   && GET_CODE (XEXP (ad, 0)) == PLUS
-	   && (XEXP (XEXP (ad, 0), 0) == frame_pointer_rtx
-#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
-	       || XEXP (XEXP (ad, 0), 0) == hard_frame_pointer_rtx
-#endif
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
-	       || XEXP (XEXP (ad, 0), 0) == arg_pointer_rtx
-#endif
-	       || XEXP (XEXP (ad, 0), 0) == stack_pointer_rtx)
+	   && GET_CODE (XEXP (XEXP (ad, 0), 0)) == REG
+	   && REGNO (XEXP (XEXP (ad, 0), 0)) < FIRST_PSEUDO_REGISTER
+	   && REG_MODE_OK_FOR_BASE_P (XEXP (XEXP (ad, 0), 0), mode)
 	   && ! memory_address_p (mode, ad))
     {
       *loc = ad = gen_rtx_PLUS (GET_MODE (ad),
@@ -4861,14 +4859,9 @@ find_reloads_address (mode, memrefloc, a
 
   else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
 	   && GET_CODE (XEXP (ad, 0)) == PLUS
-	   && (XEXP (XEXP (ad, 0), 1) == frame_pointer_rtx
-#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
-	       || XEXP (XEXP (ad, 0), 1) == hard_frame_pointer_rtx
-#endif
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
-	       || XEXP (XEXP (ad, 0), 1) == arg_pointer_rtx
-#endif
-	       || XEXP (XEXP (ad, 0), 1) == stack_pointer_rtx)
+	   && GET_CODE (XEXP (XEXP (ad, 0), 1)) == REG
+	   && REGNO (XEXP (XEXP (ad, 0), 1)) < FIRST_PSEUDO_REGISTER
+	   && REG_MODE_OK_FOR_BASE_P (XEXP (XEXP (ad, 0), 1), mode)
 	   && ! memory_address_p (mode, ad))
     {
       *loc = ad = gen_rtx_PLUS (GET_MODE (ad),

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]