Fix reload ICE with define-split

Roman Zippel zippel@linux-m68k.org
Thu Mar 1 03:41:00 GMT 2007


Hi,

On Wed, 28 Feb 2007, Nathan Sidwell wrote:

> Ian Lance Taylor wrote:
> 
> > So I'm going to approve Roman's patch, except that for increased
> > flexibility I think it should be modified to only create a REG_INC
> > note if the note does not already exist, since the backend may have
> > added the note itself.
> 
> ok.  Roman, Please check in my testcase at least :)

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.

bye, Roman


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.

        testsuite/
        * gcc.target/m68k/m68k.exp: New.
        * gcc.target/m68k/crash1.c: New.

---
 gcc/emit-rtl.c                         |   43 +++++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/m68k/crash1.c |   42 ++++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/m68k/m68k.exp |   41 +++++++++++++++++++++++++++++++
 3 files changed, 126 insertions(+)

Index: gcc/gcc/emit-rtl.c
===================================================================
--- gcc.orig/gcc/emit-rtl.c
+++ gcc/gcc/emit-rtl.c
@@ -3077,6 +3077,36 @@ 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
@@ -3242,6 +3272,19 @@ try_split (rtx pat, rtx trial, int last)
 	    }
 	  break;
 
+#ifdef AUTO_INC_DEC
+	case REG_INC:
+	  for (insn = insn_last; insn; insn = PREV_INSN (insn))
+	    {
+	      rtx reg = XEXP (note, 0);
+	      if (!find_reg_note (insn, REG_INC, 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