This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Reload bug with register elimination + reload inheritance
- From: Rask Ingemann Lambertsen <rask at sygehus dot dk>
- To: Richard Henderson <rth at redhat dot com>, gcc at gcc dot gnu dot org
- Date: Sun, 6 May 2007 02:35:25 +0200
- Subject: Re: Reload bug with register elimination + reload inheritance
- References: <20070425115134.GC3106@sygehus.dk> <20070425161152.GA26812@redhat.com> <20070426194916.GA23187@sygehus.dk> <20070426205237.GA25791@redhat.com> <20070427140013.GB23187@sygehus.dk> <20070427152411.GA16041@redhat.com> <20070501214557.GB17350@sygehus.dk>
On Tue, May 01, 2007 at 11:45:57PM +0200, Rask Ingemann Lambertsen wrote:
>
> $ ./xgcc -B./ ~/cvssrc/gcc/gcc/testsuite/gcc.dg/20020210-1.c \
> -O2 -sim=linuxvm86 -o /tmp/20020210-1-fp -fno-omit-frame-pointer
> $ /tmp/20020210-1-fp; echo $?
> 0
>
> $ ./xgcc -B./ ~/cvssrc/gcc/gcc/testsuite/gcc.dg/20020210-1.c \
> -O2 -sim=linuxvm86 -o /tmp/20020210-1-nofp -fomit-frame-pointer
> $ /tmp/20020210-1-nofp; echo $?
> 1
It looks like I have a fix:
$ ./xgcc -B./ ~/cvssrc/gcc/gcc/testsuite/gcc.dg/20020210-1.c \
-O2 -sim=linuxvm86 -o /tmp/20020210-1-nofp-ny -fomit-frame-pointer
$ /tmp/20020210-1-nofp-ny; echo $?
0
--- 20020210-1-nofp.s 2007-05-01 19:16:23.000000000 +0200
+++ 20020210-1-nofp-ny.s 2007-05-06 02:10:04.000000000 +0200
@@ -24,9 +24,13 @@
subw $10, %sp
movw %sp, %bp
pushw 22(%bp)
+ movw %sp, %bp
pushw 22(%bp)
+ movw %sp, %bp
pushw 22(%bp)
+ movw %sp, %bp
pushw 22(%bp)
+ movw %sp, %bp
pushw 22(%bp)
call bar
addw $20, %sp
Index: reload1.c
===================================================================
--- reload1.c (revision 124334)
+++ reload1.c (working copy)
@@ -2709,6 +2722,20 @@ eliminate_regs (rtx x, enum machine_mode
return eliminate_regs_1 (x, mem_mode, insn, false);
}
+/* Disable inheritance of past reloads from hard reg REG. Helper function
+ for elimination_effects(). */
+static void
+break_reload_inheritance (unsigned int reg)
+{
+ unsigned int r;
+
+ for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
+ {
+ if (reg_reloaded_contents[r] == reg)
+ CLEAR_HARD_REG_BIT (reg_reloaded_valid, r);
+ }
+}
+
/* Scan rtx X for modifications of elimination target registers. Update
the table of eliminables to reflect the changed state. MEM_MODE is
the mode of an enclosing MEM rtx, or VOIDmode if not within a MEM. */
@@ -2798,6 +2825,8 @@ elimination_effects (rtx x, enum machine
else
ep->can_eliminate = 0;
}
+ /* The offset changed, past reloads can't be inherited. */
+ break_reload_inheritance (ep->to);
}
/* These two aren't unary operators. */
@@ -2882,7 +2911,11 @@ elimination_effects (rtx x, enum machine
if (GET_CODE (src) == PLUS
&& XEXP (src, 0) == SET_DEST (x)
&& GET_CODE (XEXP (src, 1)) == CONST_INT)
- ep->offset -= INTVAL (XEXP (src, 1));
+ {
+ ep->offset -= INTVAL (XEXP (src, 1));
+ /* The offset changed, past reloads can't be inherited. */
+ break_reload_inheritance (ep->to);
+ }
else
ep->can_eliminate = 0;
}
(Heading for bed.)
--
Rask Ingemann Lambertsen