http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54398
--- Comment #5 from Carrot <carrot at google dot com> 2012-09-11 00:10:45 UTC --- It's the bug in local dse sub step in dse.c. 66 (insn/f 70 69 71 2 (set (reg/f:SI 7 r7) 67 (plus:SI (reg/f:SI 13 sp) 68 (const_int 0 [0]))) t.ii:24 -1 69 (nil)) This insn setup the hfp, r7 197 (insn 12 30 17 2 (set (mem/s/c:SI (reg/f:SI 7 r7) [4 tmp1.x+0 S4 A64]) 198 (reg:SI 12 ip [orig:137 D.1799 ] [137])) t.ii:8 694 {*thumb2_movsi_insn} 199 (nil)) This is the store instruction, the memory base address is r7, the hfp register, dse think hfp is constant inside the function, so give it a store group 221 (insn 37 36 34 2 (set (reg/f:SI 8 r8 [170]) 222 (reg/f:SI 7 r7)) t.ii:32 694 {*thumb2_movsi_insn} 223 (expr_list:REG_EQUIV (plus:SI (reg/f:SI 7 r7) 224 (const_int 0 [0])) 225 (nil))) This insn move r7 to r8, it also equals to the value of sp 245 (insn 38 35 39 2 (parallel [ 246 (set (reg:SI 0 r0) 247 (mem/s/c:SI (reg/f:SI 8 r8 [170]) [3 tmp1+0 S4 A64])) 248 (set (reg:SI 1 r1) 249 (mem/s/c:SI (plus:SI (reg/f:SI 8 r8 [170]) 250 (const_int 4 [0x4])) [3 tmp1+4 S4 A32])) 251 ]) t.ii:32 369 {*ldm2_ia} 252 (nil)) This is the load instruction, the memory base address is r8, const_or_frame_p returns false for r8, after using cselib_expand_value_rtx to r8, we get a base address sp, const_or_frame_p still return false for it. So the corresponding group id is -1 (no corresponding store group), then it can't match the store insn 12. So dse consider the memory stored in insn 12 is never used, thus a dead store, and can be eliminated. The problem is the hfp based address is considered constant base address, sp and derived addresses are considered varied base address, they will not be matched when detecting interfering memory access. But in many cases sp and hfp can be same. Even worse, addresses copied from or derived from hfp could be recognized as derived from sp, like in this case, and causes memory access mismatch.