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.

Reply via email to