optimization/5844: Bad code generated for -O2 -mcpu=i586
H . J . Lu
hjl@lucon.org
Wed Mar 6 00:02:00 GMT 2002
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",
More information about the Gcc-bugs
mailing list