This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Fix reload ICE with define-split
- From: Roman Zippel <zippel at linux-m68k dot org>
- To: Ian Lance Taylor <iant at google dot com>
- Cc: Nathan Sidwell <nathan at codesourcery dot com>, gcc-patches at gcc dot gnu dot org
- Date: Fri, 2 Mar 2007 02:24:15 +0100 (CET)
- Subject: Re: Fix reload ICE with define-split
- References: <45DEFEE5.8030905@codesourcery.com> <Pine.LNX.4.64.0702231607150.26384@scrub.home> <45E2EBA3.4010308@codesourcery.com> <Pine.LNX.4.64.0702261605060.26384@scrub.home> <45E3064C.7040002@codesourcery.com> <Pine.LNX.4.64.0702261839250.14457@scrub.home> <45E3220F.6010709@codesourcery.com> <m3tzx646xx.fsf@localhost.localdomain> <45E5A621.6060008@codesourcery.com> <Pine.LNX.4.64.0703010437520.14457@scrub.home> <m38xeh34f8.fsf@localhost.localdomain>
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