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.