https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98499

--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Sergei Trofimovich from comment #6)
> (In reply to Richard Biener from comment #5)
> > Possibly in discovering pure/constness.  See uses of
> > gimple_call_return_slot_opt_p in tree-ssa-structalias.c
> 
> Aha, that's useful!
> 
> Trying to understand the problem better myself: `-fdump-tree-all` has
> seemingly relevant `036t.ealias` that precedes breaking `037t.fre1`.
> 
> I assume `036t.ealias` analyses individual functions locally and does not
> take into account other details, thus main() analysis should be enough:

Well - it does take into account fnspecs derived by modref analysis for
Importer::Importer - specifically ...

> ```
> ...
> Points-to sets
> 
> ANYTHING = { ANYTHING }
> ESCAPED = { ESCAPED NONLOCAL }
> NONLOCAL = { ESCAPED NONLOCAL }
> STOREDANYTHING = { }
> INTEGER = { ANYTHING }
> _ZN8ImporterC1Ev = { }
> imp.0+64 = { ESCAPED NONLOCAL } same as _6
> imp.64+8 = { ESCAPED NONLOCAL }
> __builtin_trap = { }
> main = { }
> CALLUSED(9) = { ESCAPED NONLOCAL imp.0+64 imp.64+8 } same as callarg(11)
> CALLCLOBBERED(10) = { ESCAPED NONLOCAL imp.0+64 imp.64+8 } same as
> callarg(11)
> callarg(11) = { ESCAPED NONLOCAL imp.0+64 imp.64+8 }

the above shows we do not consider 'imp' to escape, and thus

> _6 = { ESCAPED NONLOCAL }

_6 does not point to 'imp'.

Relevant parts of handle_rhs_call are probably

      /* As we compute ESCAPED context-insensitive we do not gain
         any precision with just EAF_NOCLOBBER but not EAF_NOESCAPE
         set.  The argument would still get clobbered through the
         escape solution.  */
      if ((flags & EAF_NOCLOBBER)
           && (flags & (EAF_NOESCAPE | EAF_NODIRECTESCAPE)))
        {
...

specifically lines

          if (!(flags & (EAF_NOESCAPE | EAF_DIRECT)))
            make_indirect_escape_constraint (tem);

probably do not trigger because of the invalid modref analysis.  I suggest
to look at the early modref pass dump (it's after FRE but still applies
to callers)

> 
> Alias information for int main()
> 
> Aliased symbols
> 
> imp, UID D.2146, struct Importer, is addressable
> 
> Call clobber information
> 
> ESCAPED, points-to non-local, points-to vars: { }
> 
> Flow-insensitive points-to information
> 
> _6, points-to non-local, points-to escaped, points-to NULL, points-to vars:
> { }
> 
> int main ()
> {
>   struct Importer imp;
>   char * _6;
> 
>   <bb 2> :
>   Importer::Importer (&imp);
>   _6 = MEM[(struct string *)&imp]._M_buf;
>   if (&MEM[(struct string *)&imp]._M_local_buf != _6)
>     goto <bb 3>; [0.00%]
>   else
>     goto <bb 4>; [100.00%]
> 
>   <bb 3> [count: 0]:
>   __builtin_trap ();
> 
>   <bb 4> :
>   imp ={v} {CLOBBER};
>   imp ={v} {CLOBBER};
>   return 0;
> }
> ```
> 
> I think this looks correct. As I understand we care about a few things in
> the analysis here:
> 1. imp.0+64 and _6 both point to the same flow-insensitive classes (both are
> ESCAPED NONLOCAL)
> 2. imp.0+64 and _6 both point to the same field in flow-sensitive analysis
> (both do according to `imp.0+64 = { ESCAPED NONLOCAL } same as _6`.
> 
> I don't see problems here.
> 
> Mechanically looking at incorrect gcc's decision for `imp.0+64 != _6`:
> 
>   ptrs_compare_unequal(
>     ptr1 = &MEM[(struct string *)&imp]._M_local_buf,
>     ptr2 = _6
>   )
> 
> returns `TRUE` because
> 
>   pt_solution_includes(
>     info = ptr2->pt,
>     obj1 = imp
>   )
> 
> returns `FALSE`. That seems to be a bug.
> 
> Do arguments to `pt_solution_includes` look correct so far? Does it try to
> answer "could _6 point at any field of 'imp' type"?

Reply via email to