c/2404: arm-linux-gcc ice

Bernd Schmidt bernds@redhat.com
Wed Apr 4 06:26:00 GMT 2001


On 27 Mar 2001 bkohlen@intrinsyc.com wrote:

> gcc cross compiler for arm with fairly standard configure
> flags. used in combination with glibc-2.1.3 and binutils-2.10.
> I was compiling xfree86 for arm when error occured.
> >Description:
> When installing xfree86 (on my pc, so that I can package it
> for arm) it compiles shadow.c and I get the following error:
>
> shadow.c: In function `shadowImageGlyphBlt':
> shadow.c:1173: Internal compiler error in `purge_addressof_1', at function.c:3183
> Please submit a full bug report.
> See <URL: http://www.gnu.org/software/gcc/bugs.html > for instructions.

Fixed with the following patch on the 2.95 branch.  See also the original
submission
  http://gcc.gnu.org/ml/gcc-patches/1999-11/msg00218.html


Bernd

Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ChangeLog,v
retrieving revision 1.3667.4.352
diff -u -p -r1.3667.4.352 ChangeLog
--- ChangeLog	2001/04/03 14:46:04	1.3667.4.352
+++ ChangeLog	2001/04/04 13:04:35
@@ -1,3 +1,14 @@
+2001-04-04  Bernd Schmidt  <bernds@redhat.com>
+
+	Fri Nov  5 10:07:25 1999  Nick Clifton  <nickc@cygnus.com>
+	* function.c (is_addressof): New function.  Returns true if
+	the given piece of RTL is an ADDRESSOF.
+	(purge_addressof_1): Make boolean.  Return false if the
+	ADDRESSOFs could not be purged.
+	(purge_addressof): If ADDRESSOFs could not be purged from the
+	notes attached to an insn, remove the offending note(s),
+	unless they are attached to a libcall.
+
 2001-04-03  Bernd Schmidt  <bernds@redhat.com>

 	2001-03-16  Jakub Jelinek  <jakub@redhat.com>
Index: function.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/function.c,v
retrieving revision 1.90.4.6
diff -u -p -r1.90.4.6 function.c
--- function.c	2001/01/25 14:03:15	1.90.4.6
+++ function.c	2001/04/04 13:04:36
@@ -513,8 +513,9 @@ static int *record_insns	PROTO((rtx));
 static int contains		PROTO((rtx, int *));
 #endif /* HAVE_prologue || HAVE_epilogue */
 static void put_addressof_into_stack PROTO((rtx, struct hash_table *));
-static void purge_addressof_1	PROTO((rtx *, rtx, int, int,
+static boolean purge_addressof_1 PROTO((rtx *, rtx, int, int,
 				       struct hash_table *));
+static int is_addressof		PROTO ((rtx *, void *));
 static struct hash_entry *insns_for_mem_newfunc PROTO((struct hash_entry *,
 						       struct hash_table *,
 						       hash_table_key));
@@ -3055,9 +3056,10 @@ static rtx purge_addressof_replacements;

 /* Helper function for purge_addressof.  See if the rtx expression at *LOC
    in INSN needs to be changed.  If FORCE, always put any ADDRESSOFs into
-   the stack.  */
+   the stack.  If the function returns FALSE then the replacement could not
+   be made.  */

-static void
+static boolean
 purge_addressof_1 (loc, insn, force, store, ht)
      rtx *loc;
      rtx insn;
@@ -3068,13 +3070,14 @@ purge_addressof_1 (loc, insn, force, sto
   RTX_CODE code;
   int i, j;
   char *fmt;
+  boolean result = true;

   /* Re-start here to avoid recursion in common cases.  */
  restart:

   x = *loc;
   if (x == 0)
-    return;
+    return true;

   code = GET_CODE (x);

@@ -3087,7 +3090,7 @@ purge_addressof_1 (loc, insn, force, sto

       if (validate_change (insn, loc, sub, 0)
 	  || validate_replace_rtx (x, sub, insn))
-	return;
+	return true;

       start_sequence ();
       sub = force_operand (sub, NULL_RTX);
@@ -3098,7 +3101,7 @@ purge_addressof_1 (loc, insn, force, sto
       insns = gen_sequence ();
       end_sequence ();
       emit_insn_before (insns, insn);
-      return;
+      return true;
     }
   else if (code == MEM && GET_CODE (XEXP (x, 0)) == ADDRESSOF && ! force)
     {
@@ -3117,7 +3120,7 @@ purge_addressof_1 (loc, insn, force, sto
 	  && (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode))
 	{
 	  put_addressof_into_stack (XEXP (x, 0), ht);
-	  return;
+	  return true;
 	}
       else if (GET_CODE (sub) == REG && GET_MODE (x) != GET_MODE (sub))
 	{
@@ -3136,7 +3139,7 @@ purge_addressof_1 (loc, insn, force, sto
 		if (rtx_equal_p (x, XEXP (tem, 0)))
 		  {
 		    *loc = XEXP (XEXP (tem, 1), 0);
-		    return;
+		    return true;
 		  }

 	      /* See comment for purge_addressof_replacements. */
@@ -3176,11 +3179,17 @@ purge_addressof_1 (loc, insn, force, sto
 		      z = gen_lowpart (GET_MODE (x), z);

 		    *loc = z;
-		    return;
+		    return true;
 		  }

-	      /* There should always be such a replacement.  */
-	      abort ();
+	      /* Sometimes we may not be able to find the replacement.  For
+		 example when the original insn was a MEM in a wider mode,
+		 and the note is part of a sign extension of a narrowed
+		 version of that MEM.  Gcc testcase compile/990829-1.c can
+		 generate an example of this siutation.  Rather than complain
+		 we return false, which will prompt our caller to remove the
+		 offending note.  */
+	      return false;
 	    }

 	  size_x = GET_MODE_BITSIZE (GET_MODE (x));
@@ -3266,7 +3275,7 @@ purge_addressof_1 (loc, insn, force, sto
 				      purge_bitfield_addressof_replacements));

 	      /* We replaced with a reg -- all done.  */
-	      return;
+	      return true;
 	    }
 	}
       else if (validate_change (insn, loc, sub, 0))
@@ -3283,13 +3292,13 @@ purge_addressof_1 (loc, insn, force, sto
 		if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0)))
 		  {
 		    XEXP (XEXP (tem, 1), 0) = sub;
-		    return;
+		    return true;
 		  }
 	      purge_addressof_replacements
 		= gen_rtx (EXPR_LIST, VOIDmode, XEXP (x, 0),
 			   gen_rtx_EXPR_LIST (VOIDmode, sub,
 					      purge_addressof_replacements));
-	      return;
+	      return true;
 	    }
 	  goto restart;
 	}
@@ -3299,13 +3308,13 @@ purge_addressof_1 (loc, insn, force, sto
   else if (code == ADDRESSOF)
     {
       put_addressof_into_stack (x, ht);
-      return;
+      return true;
     }
   else if (code == SET)
     {
-      purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
-      purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
-      return;
+      result = purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
+      result &= purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
+      return result;
     }

   /* Scan all subexpressions. */
@@ -3313,11 +3322,13 @@ purge_addressof_1 (loc, insn, force, sto
   for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
     {
       if (*fmt == 'e')
-	purge_addressof_1 (&XEXP (x, i), insn, force, 0, ht);
+	result &= purge_addressof_1 (&XEXP (x, i), insn, force, 0, ht);
       else if (*fmt == 'E')
 	for (j = 0; j < XVECLEN (x, i); j++)
-	  purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0, ht);
+	  result &= purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0, ht);
     }
+
+  return result;
 }

 /* Return a new hash table entry in HT.  */
@@ -3437,6 +3448,16 @@ compute_insns_for_mem (insns, last_insn,
 	}
 }

+/* Helper function for purge_addressof called through for_each_rtx.
+   Returns true iff the rtl is an ADDRESSOF.  */
+static int
+is_addressof (rtl, data)
+     rtx * rtl;
+     void * data ATTRIBUTE_UNUSED;
+{
+  return GET_CODE (* rtl) == ADDRESSOF;
+}
+
 /* Eliminate all occurrences of ADDRESSOF from INSNS.  Elide any remaining
    (MEM (ADDRESSOF)) patterns, and force any needed registers into the
    stack.  */
@@ -3465,9 +3486,30 @@ purge_addressof (insns)
     if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
 	|| GET_CODE (insn) == CALL_INSN)
       {
-	purge_addressof_1 (&PATTERN (insn), insn,
-			   asm_noperands (PATTERN (insn)) > 0, 0, &ht);
-	purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, &ht);
+	if (! purge_addressof_1 (&PATTERN (insn), insn,
+				 asm_noperands (PATTERN (insn)) > 0, 0, &ht))
+	  /* If we could not replace the ADDRESSOFs in the insn,
+	     something is wrong.  */
+	  abort ();
+
+	if (! purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, &ht))
+	  {
+	    /* If we could not replace the ADDRESSOFs in the insn's notes,
+	       we can just remove the offending notes instead.  */
+	    rtx note;
+
+	    for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+	      {
+		/* If we find a REG_RETVAL note then the insn is a libcall.
+		   Such insns must have REG_EQUAL notes as well, in order
+		   for later passes of the compiler to work.  So it is not
+		   safe to delete the notes here, and instead we abort.  */
+		if (REG_NOTE_KIND (note) == REG_RETVAL)
+		  abort ();
+		if (for_each_rtx (& note, is_addressof, NULL))
+		  remove_note (insn, note);
+	      }
+	  }
       }

   /* Clean up.  */



More information about the Gcc-patches mailing list