https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67443
--- Comment #10 from Dominik Vogt <vogt at linux dot vnet.ibm.com> --- This is what's happening: Before the dse2 pass, there is a store instruction (25) followed by a read instruction later (29): --- # store first byte (insn 25 135 136 4 (set (mem/j:QI (reg/v/f:DI 2 %r2 [orig:47 ps ] [47]) [2 ps_7\ ->f1+0 S1 A32]) (reg:QI 1 %r1 [orig:51 D.2017+3 ] [51])) t67443.cxx:17 74 {*movqi} (nil)) (insn 136 25 137 4 (set (reg/v/f:DI 1 %r1 [orig:47 ps ] [47]) (reg/v/f:DI 3 %r3 [orig:47 ps ] [47])) t67443.cxx:18 63 {*movdi_64} (nil)) # overwrites r2 (insn 137 136 29 4 (set (reg:SI 2 %r2 [68]) (mem/u/c:SI (unspec:DI [ (symbol_ref/u:DI ("*.LC0") [flags 0x2]) (reg:DI 13 %r13) ] UNSPEC_LTREF) [3 S4 A32])) t67443.cxx:18 67 {*movsi_zarch} (nil)) # write three bytes (insn 29 137 139 4 (parallel [ (set (reg:SI 2 %r2 [68]) (and:SI (reg:SI 2 %r2 [68]) (mem/j:SI (reg/v/f:DI 1 %r1 [orig:47 ps ] [47]) [2 ps_7->f2\ +-1 S4 A32]))) (clobber (reg:CC 33 %cc)) ]) t67443.cxx:18 454 {*andsi3_zarch} (nil)) --- With the unpatched code, the a "value" expression is put in the mem_addr field of the store_info for the "set" (similar for the read in insn 29): store (value:DI 3:3 @0xb7049598/0xb70516a8) read (value:DI 3:3 @0xb7049598/0xb70516a8) With the patched code, the mem_addr is resolved to a register expression r2 for the store and r1 for the read: store (reg/v/f:DI 2 %r2 [orig:47 ps ] [47]) read (reg/v/f:DI 1 %r1 [orig:47 ps ] [47]) Then, canon_true_dependence is called with these terms and calls get_addr on them again. In the unpatched case, the same address value is resolved to the same register expression: (reg/v/f:DI 1 %r1 [orig:47 ps ] [47]) With the patched code, there's nothing left to do for get_addr, so there are two different register expressions that describe the same address. In the end, memrefs_conflict_p() gets called with the two different register expressions and fails to detect that they refer to the same address (which they do *not* at insn 29 because r2 has been overwritten in between). So, I'd say the new call of get_addr() in record_store() is too early because it may replace the address value by an expression that is no longer valid when the memory is read later.