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