This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: ADDRESSOF bug
- To: law at cygnus dot com, rth at cygnus dot com
- Subject: Re: ADDRESSOF bug
- From: Richard Henderson <rth at cygnus dot com>
- Date: Sat, 9 Jan 1999 23:58:45 -0800
- Cc: egcs-patches at cygnus dot com
- References: <16688.915948934@hurl.cygnus.com>
- Reply-To: Richard Henderson <rth at cygnus dot com>
On Sat, Jan 09, 1999 at 11:15:34PM -0700, Jeffrey A Law wrote:
> ------- Forwarded Message
>
> From: Jeffrey A Law <law@hurl.cygnus.com>
> To: egcs-bugs@cygnus.com
> Date: Thu, 07 Jan 1999 23:44:03 -0700
> Subject: ADDRESSOF bug
>
>
> Anyone up for what (I hope) should be a reasonably simple bug to track
> down?
>
> Configure for powerpc-ibm-aix4.1.3 and compile the attached code with -O1.
> This is keeping the ppc aix port from bootstrapping with BOOT_CFLAGS=-O1
>
> Have fun...
>
> static int
> java_double_finite (d)
> double d;
> {
> long long *ip = (long long *) &d;
> return (*ip & 0x7ff0000000000000LL ) != 0x7ff0000000000000LL ;
> }
We do a replacement on
(insn 15 13 20 (set (reg:SI 87)
(mem:SI (addressof:SI (reg/v:DF 84) 82) 0)) 402 {movsi+1} (nil)
(nil))
which is all well and good, except that when we come to
(insn 22 19 24 (set (reg:DI 86)
(reg:DI 86)) 424 {*movdi_32} (nil)
(insn_list:REG_RETVAL 20 (expr_list:REG_EQUAL (and:DI (mem:DI (addressof:SI
(reg/v:DF 84) 82) 0)
(const_int 9218868437227405312))
(nil))))
we don't find an exact match between the two mems that we replaced,
and so we abort.
In this case it is obvious that we can fix things up. I'm not sure
about the general case -- if worse comes to worse, we may just want
to delete problematic notes.
r~
* function.c (purge_addressof_1): If the note accesses a mem+addressof
in a wider mode than any replacement, adjust the cached replacement.
Index: function.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/function.c,v
retrieving revision 1.61
diff -u -p -d -r1.61 function.c
--- function.c 1998/12/16 20:55:51 1.61
+++ function.c 1999/01/10 07:48:58
@@ -2899,11 +2899,38 @@ purge_addressof_1 (loc, insn, force, sto
for (tem = purge_addressof_replacements; tem != NULL_RTX;
tem = XEXP (XEXP (tem, 1), 1))
- if (rtx_equal_p (x, XEXP (tem, 0)))
- {
- *loc = XEXP (XEXP (tem, 1), 0);
- return;
- }
+ {
+ rtx y = XEXP (tem, 0);
+ if (GET_CODE (y) == MEM
+ && rtx_equal_p (XEXP (x, 0), XEXP (y, 0)))
+ {
+ /* It can happen that the note may speak of things in
+ a wider (or just different) mode than the code did.
+ This is especially true of REG_RETVAL. */
+
+ rtx z = XEXP (XEXP (tem, 1), 0);
+ if (GET_MODE (x) != GET_MODE (y))
+ {
+ if (GET_CODE (z) == SUBREG && SUBREG_WORD (z) == 0)
+ z = SUBREG_REG (z);
+
+ /* ??? If we'd gotten into any of the really complex
+ cases below, I'm not sure we can do a proper
+ replacement. Might we be able to delete the
+ note in some cases? */
+ if ((GET_MODE_SIZE (GET_MODE (x))
+ < GET_MODE_SIZE (GET_MODE (y)))
+ || (GET_MODE_SIZE (GET_MODE (z))
+ < GET_MODE_SIZE (GET_MODE (x))))
+ abort ();
+
+ z = gen_lowpart (GET_MODE (x), z);
+ }
+
+ *loc = z;
+ return;
+ }
+ }
/* There should always be such a replacement. */
abort ();