[Bug rtl-optimization/48773] Dataflow and REG_DEAD notes

mfortune at gmail dot com gcc-bugzilla@gcc.gnu.org
Thu Apr 28 12:05:00 GMT 2011


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48773

Matthew Fortune <mfortune at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|4.3.5                       |4.6.0

--- Comment #4 from Matthew Fortune <mfortune at gmail dot com> 2011-04-28 12:03:22 UTC ---
Hello all,

I have re-produced this issue using GCC 4.6.0 targetting x86 linux. The
compiler does not produce bad code but the testcase shows how REG_DEAD notes
can be invalid in the final pass which can then cause peepholes to go wrong.
This is just one example, other passes that use REG_DEAD notes could go equally
wrong if they do not specifically analyze/run the dataflow note problem (not
sure if any other passes would actually suffer from this).

[mfortune@mfortune-linux test]$ ../tk_x86/bin/gcc -v
Using built-in specs.
COLLECT_GCC=../tk_x86/bin/gcc
COLLECT_LTO_WRAPPER=/home/mfortune/gcc-4.6.0-root/libexec/gcc/i686-pc-linux-gnu/4.6.0/lto-wrapper
Target: i686-pc-linux-gnu
Configured with: ../gcc-4.6.0/configure --prefix=/home/mfortune/gcc-4.6.0-root
--enable-languages=c --with-gmp=/home/mfortune/gcc-4.6.0-prereq/
Thread model: posix
gcc version 4.6.0 (GCC)

The second scheduling pass has to be disabled to demonstrate this particular
instance of the bug.

gcc -O2 -S -dapA inflate.i -fno-schedule-insns2

A REG_DEAD note is correctly added tgo insn 3388 in the ce3 dump:
-- ce3 --
(insn 3387 1196 1197 173 (set (reg:SI 3 bx)
        (mem/c:SI (plus:SI (reg/f:SI 7 sp)
                (const_int 60 [0x3c])) [11 %sfp+-68 S4 A32]))
lib/zlib_inflate/inflate.c:435 50 {*movsi_internal}
     (nil))

(insn 1197 3387 3388 173 (set (reg/v:SI 6 bp [orig:117 hold ] [117])
        (mem/s:SI (plus:SI (reg:SI 3 bx)
                (const_int 52 [0x34])) [5 MEM[(struct inflate_state
*)D.3891_186].hold+0 S4 A32])) lib/zlib_inflate/inflate.c:435 50
{*movsi_internal}
     (nil))

(insn 3388 1197 1198 173 (set (reg:SI 0 ax)
        (reg:SI 3 bx)) lib/zlib_inflate/inflate.c:435 50 {*movsi_internal}
     (expr_list:REG_DEAD (reg:SI 3 bx)
        (nil)))

(insn 1198 3388 3389 173 (set (reg/v:SI 3 bx [orig:138 bits ] [138])
        (mem/s:SI (plus:SI (reg:SI 0 ax)
                (const_int 56 [0x38])) [4 MEM[(struct inflate_state
*)D.3891_186].bits+0 S4 A32])) lib/zlib_inflate/inflate.c:435 50
{*movsi_internal}
     (nil))
-- end ce3 --

REG_DEAD notes are left to get out of sync as shown in cprop_hardreg dump:
-- cprop_hardreg --
(insn 3387 1196 1197 173 (set (reg:SI 3 bx)
        (mem/c:SI (plus:SI (reg/f:SI 7 sp)
                (const_int 60 [0x3c])) [11 %sfp+-68 S4 A32]))
lib/zlib_inflate/inflate.c:435 50 {*movsi_internal}
     (nil))

(insn 1197 3387 3388 173 (set (reg/v:SI 6 bp [orig:117 hold ] [117])
        (mem/s:SI (plus:SI (reg:SI 3 bx)
                (const_int 52 [0x34])) [5 MEM[(struct inflate_state
*)D.3891_186].hold+0 S4 A32])) lib/zlib_inflate/inflate.c:435 50
{*movsi_internal}
     (nil))

(insn 3388 1197 1198 173 (set (reg:SI 0 ax)
        (reg:SI 3 bx)) lib/zlib_inflate/inflate.c:435 50 {*movsi_internal}
     (expr_list:REG_DEAD (reg:SI 3 bx)
        (nil)))

(insn 1198 3388 3389 173 (set (reg/v:SI 3 bx [orig:138 bits ] [138])
        (mem/s:SI (plus:SI (reg:SI 3 bx [0])
                (const_int 56 [0x38])) [4 MEM[(struct inflate_state
*)D.3891_186].bits+0 S4 A32])) lib/zlib_inflate/inflate.c:435 50
{*movsi_internal}
     (nil))
-- end cprop_hardreg --

REG_DEAD notes are still out of sync just before final:
-- nothrow --
(insn 3387 1196 1197 237 (set (reg:SI 3 bx)
        (mem/c:SI (plus:SI (reg/f:SI 7 sp)
                (const_int 60 [0x3c])) [11 %sfp+-68 S4 A32]))
lib/zlib_inflate/inflate.c:435 50 {*movsi_internal}
     (nil))

(insn 1197 3387 3388 237 (set (reg/v:SI 6 bp [orig:117 hold ] [117])
        (mem/s:SI (plus:SI (reg:SI 3 bx)
                (const_int 52 [0x34])) [5 MEM[(struct inflate_state
*)D.3891_186].hold+0 S4 A32])) lib/zlib_inflate/inflate.c:435 50
{*movsi_internal}
     (nil))

(insn 3388 1197 1198 237 (set (reg:SI 0 ax)
        (reg:SI 3 bx)) lib/zlib_inflate/inflate.c:435 50 {*movsi_internal}
     (expr_list:REG_DEAD (reg:SI 3 bx)
        (nil)))

(insn 1198 3388 1199 237 (set (reg/v:SI 3 bx [orig:138 bits ] [138])
        (mem/s:SI (plus:SI (reg:SI 3 bx [0])
                (const_int 56 [0x38])) [4 MEM[(struct inflate_state
*)D.3891_186].bits+0 S4 A32])) lib/zlib_inflate/inflate.c:435 50
{*movsi_internal}
     (nil))
-- end nothrow --

This sequence of code 'could' then have a peephole applied to it such that the
bx register is replaced with ax in insns 3387, 1197 and insn 3388 is deleted.
There is no such peephole for i386 but other architectures do have peepholes
that rely on REG_DEAD notes being correct.

Attached inflate.i and full dumps for the ce3 and nothrow passes mentioned
above with REG_DEAD_DEBUGGING enabled

regards,
Matthew



More information about the Gcc-bugs mailing list