https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92462
--- Comment #19 from Wilco <wilco at gcc dot gnu.org> --- (In reply to Richard Biener from comment #18) > So I see before DSE1: > > (insn 16 15 17 2 (set (mem/c:SI (plus:SI (reg/f:SI 102 sfp) > (const_int -8 [0xfffffffffffffff8])) [1 cur+0 S4 A64]) > (reg:SI 119 [ _13 ])) "t.ii":46:14 241 {*arm_movsi_insn} > (expr_list:REG_DEAD (reg:SI 119 [ _13 ]) > (nil))) > (insn 17 16 18 2 (set (reg/f:SI 125) > (plus:SI (reg/f:SI 102 sfp) > (const_int -8 [0xfffffffffffffff8]))) "t.ii":48:26 7 > {*arm_addsi3} > (nil)) > (insn 18 17 19 2 (set (reg/f:SI 120 [ _14 ]) > (plus:SI (reg/f:SI 125) > (reg/v:SI 118 [ offset ]))) "t.ii":48:26 7 {*arm_addsi3} > (nil)) > (insn 19 18 21 2 (set (reg:SI 126) > (const_int 1 [0x1])) "t.ii":48:26 241 {*arm_movsi_insn} > (nil)) > (insn 21 19 22 2 (set (mem:QI (plus:SI (reg/f:SI 125) > (reg/v:SI 118 [ offset ])) [0 *_14+0 S1 A8]) > (subreg:QI (reg:SI 126) 0)) "t.ii":48:26 251 {*arm_movqi_insn} > (expr_list:REG_DEAD (reg:SI 126) > (nil))) > (insn 22 21 23 2 (set (reg:SI 113 [ prephitmp_6 ]) > (mem/c:SI (plus:SI (reg/f:SI 102 sfp) > (const_int -8 [0xfffffffffffffff8])) [1 cur+0 S4 A64])) > "t.ii":50:18 241 {*arm_movsi_insn} > (nil)) > > where DSE1 then replaces the load in insn 22 with (reg:SI 119) (via a new > pseudo). But clearly insn 21 clobbers it (using alias-set zero). This > is on GIMPLE > > cur = _13; > _14 = &cur + offset_12; > *_14 = 1; > pretmp_22 = cur; > > not sure why DSE1 performs CSE (heh), but clearly what it does is wrong. > And yeah, probably tree PRE "enables" this miscompilation. DSE has > some special case with frame pointer bases and constant offsets. > > But the target dependency might come in via section anchors since I see > > **scanning insn=21 > mem: (plus:SI (reg/f:SI 125) > (reg/v:SI 118 [ offset ])) > > after canon_rtx address: (plus:SI (plus:SI (reg/f:SI 102 sfp) > (reg/v:SI 118 [ offset ])) > (const_int -8 [0xfffffffffffffff8])) > > after cselib_expand address: (plus:SI (plus:SI (and:SI (symbol_ref:SI > ("*.LANCHOR0") [flags 0x182]) > (const_int 3 [0x3])) > (reg/f:SI 102 sfp)) > (const_int -8 [0xfffffffffffffff8])) > > after canon_rtx address: (plus:SI (plus:SI (and:SI (symbol_ref:SI > ("*.LANCHOR0") [flags 0x182]) > (const_int 3 [0x3])) > (reg/f:SI 102 sfp)) > (const_int -8 [0xfffffffffffffff8])) > varying cselib base=11:1018534969 offset = -8 > processing cselib store [-8..-7) > mems_found = 1, cannot_delete = false > > where it's odd that we end up with an address like this? I suspect that > base_alias_check (my special friend) disambiguates the stack-based > access with one that now appears as a *.LANCHOR0 based one. > > We call canon_true_dependence with > > (plus:SI (value:SI 11:1018534969 @0x3089c60/0x30f5ed0) > (const_int -8 [0xfffffffffffffff8])) > > for this and get_addr turns it into > > (plus:SI (plus:SI (and:SI (symbol_ref:SI ("*.LANCHOR0") [flags 0x182]) > (const_int 3 [0x3])) > (value:SI 8:8 @0x3089c18/0x30f5e40)) > (const_int -8 [0xfffffffffffffff8])) > > and indeed find_base_term returns > > (symbol_ref:SI ("*.LANCHOR0") [flags 0x182]) > > for this. Which "obviously" doesn't alias with the stack based address > because that one is "unique_base_value_p" (address:SI -3) so we win here: > > 2229 if (unique_base_value_p (x_base) || unique_base_value_p (y_base)) > 2230 return 0; > > now I wonder where that LANCHOR thing comes from. arm folks? Well when you do: int *p = &local + ((intptr_t)&global & 3); then you get the above expression when the global is addressed via an anchor. But whether or not a target uses anchors doesn't matter - the example still fails with -O1 -fno-section-anchors. So I'm wondering whether the issue is in the special code that tries to interpret an AND in an address, and mistakes the base as the symbol_ref eventhough the real base is sfp.