[Bug rtl-optimization/47612] New: RTL crash when cc0 setter moved away from cc0 user
ian at airs dot com
gcc-bugzilla@gcc.gnu.org
Fri Feb 4 20:31:00 GMT 2011
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47612
Summary: RTL crash when cc0 setter moved away from cc0 user
Product: gcc
Version: 4.6.0
Status: UNCONFIRMED
Keywords: ice-on-valid-code
Severity: normal
Priority: P3
Component: rtl-optimization
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: ian@airs.com
Consider this C file:
extern void e (int) __attribute__ ((noreturn));
void
f (char *p, int a, int b, int c)
{
int i, j;
j = 0;
for (i = 0; i < 10; ++i)
{
switch (a)
{
case 0:
p[i] = 0;
break;
case 1:
if (c == 1)
{
if (j < 0 | b <= j)
e (0);
p[j] = 0;
}
else
{
if (j < 0 | b <= j)
e (0);
p[j] = 0;
}
j++;
}
}
}
When I use a compiler built for the m68k-rtems4.11 target, the compiler crashes
when I compile this file with the options -O2 -mcpu=5206 -fwrapv.
/home/iant/gcc/m68k-rtems-objdir/./gcc/xgcc
-B/home/iant/gcc/m68k-rtems-objdir/./gcc/ -O2 -mcpu=5206 -S -fwrapv foo.c
foo.c: In function 'f':
foo.c:31:1: internal compiler error: in maybe_add_or_update_dep_1, at
sched-deps.c:845
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
I will describe what I think is happening, although I have not proved it. The
crash occurs because try_head_merge_bb in cfgcleanup.c moves a CC0-setter away
from the CC0-user. It finds a common sequence in two basic blocks--I believe
it is the finding of this common sequence which makes this test requires the
-mcpu=5206 -fwrapv options. Finding the common sequence respects CC0
requirements. However, it then calls can_move_insns_across. That returns
false, because there is a register conflict--d0 is used by the predecessor
block and the common sequence. However, can_move_insns_across also returns
move_upto, indicating which insns may be moved. can_move_insns_across does not
check for cc0 when setting move_upto, and try_head_merge_bb doesn't check for
it when using move_upto. The effect is that the cc0 setter is moved, leaving
the cc0 user behind. This leads to the later crash.
More information about the Gcc-bugs
mailing list