Fix reload ICE with define-split

Roman Zippel zippel@linux-m68k.org
Fri Mar 2 01:24:00 GMT 2007


Hi,

On Thu, 28 Feb 2007, Ian Lance Taylor wrote:

> Roman Zippel <zippel@linux-m68k.org> writes:
> 
> > Ok, I added the find_reg_note check and the test. I hope the change is 
> > simple enough so I don't have to retest the whole thing :) (which may take 
> > a few days), but I verified that it does the right thing with a cross 
> > compiler.
> 
> You do need to at least bootstrap this change on a primary platform.
> You don't necessarily need to do so on an m68k.

Ok, I did this on i686-linux and also rechecked with a cross compiler.
I changed it to use FIND_REG_INC_NOTE and to make the bootstrap worthwile 
I also added the small look cleanups from Nathan's patch.

> > +  switch (GET_CODE (x)) {
> 
> Formatting is wrong--the { should be on the next line.

Damn habits. :)

bye, Roman


gcc/
2007-xx-xx  Roman Zippel <zippel@linux-m68k.org>
            Nathan Sidwell  <nathan@codesourcery.com>

        * emit-rtl.c (find_auto_inc): New.
        (try_split): recreate REG_INC notes,
	Use regular for loops rather than whiles.

gcc/testsuite/
2007-xx-xx  Nathan Sidwell  <nathan@codesourcery.com>
        * gcc.target/m68k/m68k.exp: New.
        * gcc.target/m68k/crash1.c: New.

---
 gcc/emit-rtl.c                         |   56 +++++++++++++++++++++++++++------
 gcc/testsuite/gcc.target/m68k/crash1.c |   42 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/m68k/m68k.exp |   41 ++++++++++++++++++++++++
 3 files changed, 130 insertions(+), 9 deletions(-)

Index: gcc/gcc/emit-rtl.c
===================================================================
--- gcc.orig/gcc/emit-rtl.c
+++ gcc/gcc/emit-rtl.c
@@ -3077,6 +3077,37 @@ prev_cc0_setter (rtx insn)
 }
 #endif
 
+#ifdef AUTO_INC_DEC
+/* Find a RTX_AUTOINC class rtx which matches DATA.  */
+
+static int
+find_auto_inc (rtx *xp, void *data)
+{
+  rtx x = *xp;
+  rtx reg = data;
+
+  if (GET_RTX_CLASS (GET_CODE (x)) != RTX_AUTOINC)
+    return 0;
+
+  switch (GET_CODE (x))
+    {
+      case PRE_DEC:
+      case PRE_INC:
+      case POST_DEC:
+      case POST_INC:
+      case PRE_MODIFY:
+      case POST_MODIFY:
+	if (rtx_equal_p (reg, XEXP (x, 0)))
+	  return 1;
+	break;
+
+      default:
+	gcc_unreachable ();
+    }
+  return -1;
+}
+#endif
+
 /* Increment the label uses for all labels present in rtx.  */
 
 static void
@@ -3201,8 +3232,7 @@ try_split (rtx pat, rtx trial, int last)
       switch (REG_NOTE_KIND (note))
 	{
 	case REG_EH_REGION:
-	  insn = insn_last;
-	  while (insn != NULL_RTX)
+	  for (insn = insn_last; insn != NULL_RTX; insn = PREV_INSN (insn))
 	    {
 	      if (CALL_P (insn)
 		  || (flag_non_call_exceptions && INSN_P (insn)
@@ -3211,37 +3241,45 @@ try_split (rtx pat, rtx trial, int last)
 		  = gen_rtx_EXPR_LIST (REG_EH_REGION,
 				       XEXP (note, 0),
 				       REG_NOTES (insn));
-	      insn = PREV_INSN (insn);
 	    }
 	  break;
 
 	case REG_NORETURN:
 	case REG_SETJMP:
-	  insn = insn_last;
-	  while (insn != NULL_RTX)
+	  for (insn = insn_last; insn != NULL_RTX; insn = PREV_INSN (insn))
 	    {
 	      if (CALL_P (insn))
 		REG_NOTES (insn)
 		  = gen_rtx_EXPR_LIST (REG_NOTE_KIND (note),
 				       XEXP (note, 0),
 				       REG_NOTES (insn));
-	      insn = PREV_INSN (insn);
 	    }
 	  break;
 
 	case REG_NON_LOCAL_GOTO:
-	  insn = insn_last;
-	  while (insn != NULL_RTX)
+	  for (insn = insn_last; insn != NULL_RTX; insn = PREV_INSN (insn))
 	    {
 	      if (JUMP_P (insn))
 		REG_NOTES (insn)
 		  = gen_rtx_EXPR_LIST (REG_NOTE_KIND (note),
 				       XEXP (note, 0),
 				       REG_NOTES (insn));
-	      insn = PREV_INSN (insn);
 	    }
 	  break;
 
+#ifdef AUTO_INC_DEC
+	case REG_INC:
+	  for (insn = insn_last; insn != NULL_RTX; insn = PREV_INSN (insn))
+	    {
+	      rtx reg = XEXP (note, 0);
+	      if (!FIND_REG_INC_NOTE (insn, reg)
+		  && for_each_rtx (&PATTERN (insn), find_auto_inc, reg) > 0)
+		REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, reg,
+						      REG_NOTES (insn));
+	    }
+	  break;
+#endif
+
 	default:
 	  break;
 	}
Index: gcc/gcc/testsuite/gcc.target/m68k/crash1.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/m68k/crash1.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fomit-frame-pointer" } */
+
+/* Caused an ICE because of forgotten auto increment.  */
+
+register void *current __asm__("%a2");
+
+struct kernel_stat
+{
+ long long user;
+ long long nice;
+ long long system;
+ long long idle;
+ long long steal;
+ unsigned irqs[256];
+};
+extern struct kernel_stat per_cpu__kstat;
+
+void show_stat(void)
+{
+  int i;
+  long long user, nice, system, idle, steal;
+  long long sum = 0;
+
+  user = nice = system = idle = steal = 0;
+  for (i = 0; i < 1; i++)
+    {
+      int j;
+      user = user + per_cpu__kstat.user;
+      nice = nice + per_cpu__kstat.nice;
+      system = system + per_cpu__kstat.system;
+      idle = idle + per_cpu__kstat.idle;
+      steal = steal + per_cpu__kstat.steal;
+
+      for (j = 0 ; j < 256 ; j++)
+	sum += per_cpu__kstat.irqs[j];
+    }
+  seq_printf(user, nice, system, idle, steal);
+  seq_printf(sum);
+  for (i = 0; i < 256; i++)
+    seq_printf (i);
+}
Index: gcc/gcc/testsuite/gcc.target/m68k/m68k.exp
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/m68k/m68k.exp
@@ -0,0 +1,41 @@
+# Copyright (C) 1997, 2004, 2006 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't an m68k target.
+if ![istarget m68k*-*-*] then {
+  return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+    set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
+	"" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish



More information about the Gcc-patches mailing list