This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
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),