https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68955
--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So, we have before DSE2: ... (insn 525 192 458 12 (set (reg:SI 1 dx [orig:247 ivtmp.44 ] [247]) (mem/c:SI (plus:SI (reg/f:SI 6 bp) (const_int -76 [0xffffffffffffffb4])) [4 %sfp+-52 S4 A32])) pr68955.c:27 86 {*movsi_internal} (nil)) (insn 458 525 524 12 (set (reg:SI 0 ax [orig:247 ivtmp.44 ] [247]) (reg:SI 1 dx [orig:247 ivtmp.44 ] [247])) pr68955.c:27 86 {*movsi_internal} (nil)) (insn 524 458 194 12 (set (reg:SI 4 si [orig:124 _95 ] [124]) (mem/c:SI (plus:SI (reg/f:SI 6 bp) (const_int -80 [0xffffffffffffffb0])) [4 %sfp+-56 S4 A32])) pr68955.c:27 86 {*movsi_internal} (nil)) (insn 194 524 523 12 (set (mem:SI (reg:SI 0 ax [orig:247 ivtmp.44 ] [247]) [2 MEM[base: _165, offset: 0B]+0 S4 A32]) (reg:SI 4 si [orig:124 _95 ] [124])) pr68955.c:27 86 {*movsi_internal} (nil)) (note 523 194 567 12 NOTE_INSN_DELETED) (insn 567 523 460 12 (set (reg:SI 2 cx [orig:125 pretmp_96 ] [125]) (mem/c:SI (plus:SI (reg/f:SI 6 bp) (const_int -84 [0xffffffffffffffac])) [4 %sfp+-60 S4 A32])) pr68955.c:28 86 {*movsi_internal} (nil)) (insn 460 567 196 12 (set (reg:SI 0 ax [orig:125 pretmp_96 ] [125]) (reg:SI 2 cx [orig:125 pretmp_96 ] [125])) pr68955.c:28 86 {*movsi_internal} (nil)) (insn 196 460 598 12 (set (mem/c:SI (const:SI (plus:SI (symbol_ref:SI ("i") [flags 0x2] <var_decl 0x7f7a8d2c0090 i>) (const_int 308 [0x134]))) [2 i+308 S4 A32]) (reg:SI 0 ax [orig:125 pretmp_96 ] [125])) pr68955.c:28 86 {*movsi_internal} (nil)) (insn 598 196 197 12 (set (reg:SI 0 ax [orig:209 ivtmp.42 ] [209]) (mem/c:SI (plus:SI (reg/f:SI 6 bp) (const_int -28 [0xffffffffffffffe4])) [4 %sfp+-4 S4 A32])) pr68955.c:26 86 {*movsi_internal} (nil)) (insn 197 598 198 12 (set (reg:CCGC 17 flags) (compare:CCGC (reg:SI 5 di [orig:122 _93 ] [122]) (mem:SI (plus:SI (reg:SI 0 ax [orig:209 ivtmp.42 ] [209]) (const_int 20 [0x14])) [2 MEM[base: _327, offset: 20B]+0 S4 A32]))) pr68955.c:26 7 {*cmpsi_1} (nil)) ... and the bug IMHO is that the read in 197 can alias the store in insn 194 (well, in the testcase for e == 0, h == 2 it actually is some later read, insn 194 is from unrolled k == 0, 197 from k == 1, while the actual problem on the testcase occurs on k <= 4 store vs. k == 5 first read, but the alias oracle really doesn't know this), but during check_mem_read_rtx we call canon_true_dependence with: (gdb) p debug_rtx (mem) (mem:SI (reg:SI 0 ax [orig:247 ivtmp.44 ] [247]) [2 MEM[base: _165, offset: 0B]+0 S4 A32]) (gdb) p mem_mode $41 = SImode (gdb) p debug_rtx (mem_addr) (reg:SI 0 ax [orig:247 ivtmp.44 ] [247]) (gdb) p debug_rtx (x) (mem:SI (plus:SI (reg:SI 0 ax [orig:209 ivtmp.42 ] [209]) (const_int 20 [0x14])) [2 MEM[base: _327, offset: 20B]+0 S4 A32]) (gdb) p debug_rtx (x_addr) (plus:SI (reg:SI 0 ax [orig:209 ivtmp.42 ] [209]) (const_int 20 [0x14])) arguments and that tells us that the two can't alias, because memrefs_conflict_p returns that they don't. That is because it sees register %eax used as base address of both, one memory is biased by offset 20 and the other is not, and both sizes are 4 bytes. That is true, except the register contains different value in between the two instructions. So, the question is why nothing (get_addr?) has not converted the memory addresses into VALUEs.