https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113255
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- DSE thinks the store is dead because it falls off the function. (insn 41 40 46 4 (set (mem/c:SI (plus:DI (reg/f:DI 19 frame) (const_int -36 [0xffffffffffffffdc])) [2 e[1].y+0 S4 A32]) (reg:SI 98 [ e$1$y ])) "t.c":21:9 85 {*movsi_internal} (expr_list:REG_DEAD (reg:SI 98 [ e$1$y ]) (nil))) ... (insn 64 63 68 4 (parallel [ (set (reg:DI 131) (const_int 0 [0])) (set (reg/f:DI 129) (plus:DI (ashift:DI (reg:DI 131) (const_int 3 [0x3])) (reg/f:DI 129))) (set (reg/f:DI 119) (plus:DI (ashift:DI (reg:DI 131) (const_int 3 [0x3])) (reg/f:DI 119))) (set (mem/c:BLK (reg/f:DI 129) [1 A64]) (mem/c:BLK (reg/f:DI 119) [1 A8])) (use (reg:DI 131)) ]) "t.c":21:9 1416 {*rep_movdi_rex64} (expr_list:REG_UNUSED (reg:DI 131) (expr_list:REG_UNUSED (reg/f:DI 129) (expr_list:REG_UNUSED (reg/f:DI 119) (nil))))) it appears to be a bit convoluted how we compute the source of the block copy (reg/f:DI 119) and this is probably confusing "frame related" vs. non-frame-related MEM disambiguation. I'm unsure the above parallel is valid, isn't parallel executing stmts in "parallel" (unspecified order)? **scanning insn=64 mem: (reg/f:DI 119) after canon_rtx address: (reg/f:DI 119) after cselib_expand address: (minus:DI (plus:DI (reg/f:DI 129) (reg/f:DI 133)) (reg/f:DI 134)) after canon_rtx address: (minus:DI (plus:DI (reg/f:DI 129) (reg/f:DI 133)) (reg/f:DI 134)) varying cselib base=17:1741806 offset = 0 processing cselib load mem:(mem/c:BLK (reg/f:DI 119) [1 A8]) processing cselib load against insn 55 removing from active insn=55 has store processing cselib load against insn 47 removing from active insn=47 has store processing cselib load against insn 41 mems_found = 0, cannot_delete = true we're calling canon_true_dependence with (gdb) p debug_rtx (store_info->mem) (mem/c:SI (plus:DI (reg/f:DI 19 frame) (const_int -36 [0xffffffffffffffdc])) [2 e[1].y+0 S4 A32]) (gdb) p debug_rtx (mem) (mem/c:BLK (reg/f:DI 119) [1 A8]) (gdb) p debug_rtx (mem_addr) (minus:DI (plus:DI (value:DI 8:1741643 @0x49c8ba8/0x49b8e80) (value:DI 11:11 @0x49c8bf0/0x49b8f10)) (value:DI 9:9 @0x49c8bc0/0x49b8eb0)) and find_base_term of the mem_addr is returning (symbol_ref:DI ("g_e") [flags 0x2] <var_decl 0x7ffff7019c60 g_e>) which is because of the weird way we compute the source address (involving the address of the destination). There's a very old bug about find_base_term which tends to pick up a wrong base if multiple candidates are involved. I can't decipher this from what expand generates but the problem lies there (the rep_8bytes expansion).