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.

Reply via email to