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]

Re: ADDRESSOF bug


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 ();


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