[Bug middle-end/48770] [4.7 Regression] wrong code with -O -fprofile-arcs -fPIC -fno-dce -fno-forward-propagate -fno-tree-forwprop

law at redhat dot com gcc-bugzilla@gcc.gnu.org
Tue May 10 16:29:00 GMT 2011


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

Jeffrey A. Law <law at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
         AssignedTo|unassigned at gcc dot       |law at redhat dot com
                   |gnu.org                     |

--- Comment #6 from Jeffrey A. Law <law at redhat dot com> 2011-05-10 15:52:15 UTC ---
We have a block-local equivalence between a pseudo and a memory location:

(insn 86 85 87 9 (set (reg/f:DI 0 ax [113])
        (const:DI (plus:DI (symbol_ref:DI ("*.LPBX1") [flags 0x2] <var_decl
0x7ffff7dec3c0 *.LPBX1>)
                (const_int 8 [0x8])))) 62 {*movdi_internal_rex64}
     (expr_list:REG_EQUIV (const:DI (plus:DI (symbol_ref:DI ("*.LPBX1") [flags
0x2] <var_decl 0x7ffff7dec3c0 *.LPBX1>)
                (const_int 8 [0x8])))
        (nil)))
(insn 87 86 88 9 (set (reg:DI 114 [ *.LPBX1+8 ])
        (mem/s/j/c:DI (reg/f:DI 0 ax [113]) [0 *.LPBX1+8 S8 A64])) 62
{*movdi_internal_rex64}
     (expr_list:REG_DEAD (reg/f:DI 0 ax [113])
        (expr_list:REG_EQUIV (mem/s/j/c:DI (reg/f:DI 0 ax [113]) [0 *.LPBX1+8
S8 A64])
            (nil))))
(insn 88 87 91 9 (parallel [
            (set (reg:DI 2 cx [orig:95 *.LPBX1_I_lsm.5 ] [95])
                (plus:DI (reg:DI 114 [ *.LPBX1+8 ])
                    (const_int 1 [0x1])))
            (clobber (reg:CC 17 flags))
        ]) 253 {*adddi_1}
     (expr_list:REG_DEAD (reg:DI 114 [ *.LPBX1+8 ])
        (expr_list:REG_UNUSED (reg:CC 17 flags)
            (expr_list:REG_EQUAL (plus:DI (mem/s/j/c:DI (const:DI (plus:DI
(symbol_ref:DI ("*.LPBX1") [flags 0x2] <var_decl 0x7ffff7dec3c0 *.LPBX1>)
                                (const_int 8 [0x8]))) [0 *.LPBX1+8 S8 A64])
                    (const_int 1 [0x1]))
                (nil)))))


reg114 is marked as equivalent to (mem (reg 113)); reg114 does not get a hard
reg.  As usual, reload deletes the insn that creates the equivalence between
reg114 and its memory location (insn 87).  delete_dead_insn decides to peek at
insn86 and decides that insn86 is dead as well, which removes the
initialization of reg113.

Later reg114 is replaced with its equivalent memory location which results in
an uninitialized reference to reg113 and reading from an invalid memory
location and the segfault.

What's interesting here is delete_dead_insn's behavior -- it's been like this
since circa 1991, well before we ran any kind of real dead code elimination
after reload.  The solution *may* be to remove the recursion in
delete_dead_insn.  I'm still investigating.



More information about the Gcc-bugs mailing list