Deadly optimization bug (all gcc versions!)
Franz Sirl
Franz.Sirl-kernel@lauterbach.com
Mon Aug 16 14:43:00 GMT 1999
Am Mon, 16 Aug 1999 schrieb David Edelsohn:
>>>>>> veksler writes:
>
>veksler> The bug shows itself on gcc-2.7.0 gcc-2.7.2.1, egcs-1.0.1, egcs-1.1.2,
>veksler> gcc-2.95.
>veksler> On AIX-4.1, Linux-x86 (RH4.2 and RH6.0).
>
> This means that you have seen the bug in both PowerPC and IA-32
>code generation? I definitely see it in PowerPC. A whole group of
>instructions disappear between flow and combine. Also, -O3 with inlining
>seems to produce correct results. Maybe combine is trying some alternate
>instructions, failing, and then not properly restoring the instructions?
Currently I'm lost in try_combine(). It is called by this code around line 660
in combine.c:
/* Try combining an insn with two different insns whose results it
uses. */
for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
for (nextlinks = XEXP (links, 1); nextlinks;
nextlinks = XEXP (nextlinks, 1))
if ((next = try_combine (insn, XEXP (links, 0),
XEXP (nextlinks, 0))) != 0)
goto retry;
After the call to try_combine the instructions are deleted. try_combine is
entered with:
(gdb) p debug_rtx(i3)
(insn 22 20 24 (set (reg:SI 86)
(lshiftrt:SI (reg:SI 3 r3)
(const_int 1 [0x1]))) 52 {*addsi3_internal1} (insn_list 14 (insn_list 20 (nil)))
(expr_list:REG_DEAD (reg/v:SI 85)
(expr_list:REG_DEAD (reg:SI 87)
(nil))))
$134 = void
(gdb) p debug_rtx(i2)
(insn 20 17 22 (set (reg:SI 87)
(lshiftrt:SI (reg/v:SI 84)
(const_int 1 [0x1]))) 211 {lshrsi3_no_power} (insn_list 17 (nil))
(expr_list:REG_DEAD (reg/v:SI 84)
(nil)))
$135 = void
(gdb) p debug_rtx(i1)
(insn 14 11 17 (set (reg/v:SI 85)
(lshiftrt:SI (reg:SI 3 r3)
(const_int 1 [0x1]))) 211 {lshrsi3_no_power} (nil)
(expr_list:REG_DEAD (reg:SI 3 r3)
(nil)))
and this instruction list:
(note 7 6 8 "" NOTE_INSN_FUNCTION_BEG)
(note 8 7 10 "" NOTE_INSN_DELETED)
(note 10 8 11 0 NOTE_INSN_BLOCK_BEG)
(insn 11 10 14 (parallel[
(set (reg/v:SI 84)
(and:SI (reg:SI 4 r4)
(const_int 1 [0x1])))
(clobber (scratch:CC))
] ) 121 {andsi3} (nil)
(expr_list:REG_DEAD (reg:SI 4 r4)
(expr_list:REG_UNUSED (scratch:CC)
(nil))))
(insn 14 11 17 (set (reg/v:SI 85)
(lshiftrt:SI (reg:SI 3 r3)
(const_int 1 [0x1]))) 211 {lshrsi3_no_power} (nil)
(expr_list:REG_DEAD (reg:SI 3 r3)
(nil)))
(insn 17 14 20 (set (reg/v:SI 84)
(plus:SI (reg/v:SI 84)
(const_int 1 [0x1]))) 52 {*addsi3_internal1} (insn_list 11 (nil))
(nil))
(insn 20 17 22 (set (reg:SI 87)
(lshiftrt:SI (reg/v:SI 84)
(const_int 1 [0x1]))) 211 {lshrsi3_no_power} (insn_list 17 (nil))
(expr_list:REG_DEAD (reg/v:SI 84)
(nil)))
(insn 22 20 24 (set (reg:SI 86)
(plus:SI (reg/v:SI 85)
(reg:SI 87))) 52 {*addsi3_internal1} (insn_list 14 (insn_list 20 (nil)))
(expr_list:REG_DEAD (reg/v:SI 85)
(expr_list:REG_DEAD (reg:SI 87)
(nil))))
(insn 24 22 25 (set (reg/i:SI 3 r3)
(reg:SI 86)) 426 {movsi+1} (insn_list 22 (nil))
(expr_list:REG_DEAD (reg:SI 86)
(nil)))
(insn 25 24 29 (use (reg/i:SI 3 r3)) -1 (insn_list 24 (nil))
(expr_list:REG_DEAD (reg/i:SI 3 r3)
(nil)))
(note 29 25 0 0 NOTE_INSN_BLOCK_END)
Later on around line 2250:
/* We now know that we can do this combination. Merge the insns and
update the status of registers and LOG_LINKS. */
{
rtx i3notes, i2notes, i1notes = 0;
newi2pat is NULL here and newpat is:
(gdb) p debug_rtx(newpat)
(set (reg:SI 86)
(lshiftrt:SI (reg:SI 3 r3)
(const_int 1 [0x1])))
So I believe something already has gone wrong til here. If somebody can give me
a hint where to look closer from here... Otherwise I'm lost in this
megafunction.
Franz.
More information about the Gcc
mailing list