This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: optimization/5844: Bad code generated for -O2 -mcpu=i586
- From: "H . J . Lu" <hjl at lucon dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 6 Mar 2002 00:02:18 -0800
- Subject: Re: optimization/5844: Bad code generated for -O2 -mcpu=i586
- References: <20020305182642.A6139@lucon.org>
On Tue, Mar 05, 2002 at 06:26:42PM -0800, H . J . Lu wrote:
> The bug is in copyprop_hardreg_forward. It turns
>
> (insn 83 35 84 (set (reg:SI 0 eax)
> (mem/s:SI (plus:SI (reg/v/f:SI 2 ecx [58])
> (const_int 4 [0x4])) [4 <variable>.uncaughtExceptions+0 S4 A32])) -1 (nil)
> (nil))
>
> (insn 84 83 85 (parallel[
> (set (reg:SI 0 eax)
> (plus:SI (reg:SI 0 eax)
> (const_int 1 [0x1])))
> (clobber (reg:CC 17 flags))
> ] ) -1 (nil)
> (expr_list:REG_UNUSED (reg:CC 17 flags)
> (nil)))
>
> (insn 85 84 40 (set (mem/s:SI (plus:SI (reg/v/f:SI 2 ecx [58])
> (const_int 4 [0x4])) [4 <variable>.uncaughtExceptions+0 S4
> A32])
> (reg:SI 0 eax)) -1 (nil)
> (expr_list:REG_DEAD (reg:SI 0 eax)
> (nil)))
>
> into
>
> (insn 83 35 84 (set (reg:SI 0 eax)
> (mem/s:SI (plus:SI (reg:SI 0 eax [58])
> (const_int 4 [0x4])) [4 <variable>.uncaughtExceptions+0 S4
> A32])
> ) 45 {*movsi_1} (nil)
> (nil))
>
> (insn 84 83 85 (parallel[
> (set (reg:SI 0 eax)
> (plus:SI (reg:SI 0 eax)
> (const_int 1 [0x1])))
> (clobber (reg:CC 17 flags))
> ] ) 207 {*addsi_1} (nil)
> (expr_list:REG_UNUSED (reg:CC 17 flags)
> (nil)))
>
> (insn 85 84 40 (set (mem/s:SI (plus:SI (reg:SI 0 eax [58])
> (const_int 4 [0x4])) [4 <variable>.uncaughtExceptions+0 S4
> A32])
> (reg:SI 0 eax)) 45 {*movsi_1} (nil)
> (expr_list:REG_DEAD (reg:SI 0 eax [58])
> (nil)))
>
>
> When it sees
>
> (insn 83 35 84 (set (reg:SI 0 eax)
> (mem/s:SI (plus:SI (reg/v/f:SI 2 ecx [58])
> (const_int 4 [0x4])) [4 <variable>.uncaughtExceptions+0 S4 A32])) -1 (nil)
> (nil))
>
> It believes it can replace ecx with eax since it uses the value data
> from its predecessor where eax == ecx. Shouldn't it update the value
> data before passing it to copyprop_hardreg_forward_1?
>
>
It is wrong for replace_oldest_value_reg to use the destination of a
set insn to replace the source of it even if they are the same at that
insn. After that insn, they won't be the same anymore. This patch
seems to fix my testcase.
H.J.
----
2002-03-05 H.J. Lu (hjl@gnu.org)
* regrename.c (replace_oldest_value_reg): Don't use the
destination of a set to replace the register.
--- gcc/regrename.c.i586 Sat Feb 23 13:03:18 2002
+++ gcc/regrename.c Tue Mar 5 23:42:08 2002
@@ -1349,7 +1349,12 @@ replace_oldest_value_reg (loc, class, in
struct value_data *vd;
{
rtx new = find_oldest_value_reg (class, *loc, vd);
- if (new)
+ rtx set = single_set (insn);
+
+ /* We can't replace *LOC with NEW if NEW is the same as the
+ destination of SET. */
+ if (new && !(set && REG_P (SET_DEST (set))
+ && REGNO (SET_DEST (set)) == REGNO (new)))
{
if (rtl_dump_file)
fprintf (rtl_dump_file, "insn %u: replaced reg %u with %u\n",