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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P3                          |P2

--- Comment #17 from Richard Biener <rguenth at gcc dot gnu.org> ---
  int resultIsStatic = 1;
  func t ={&resultIsStatic};
  map_to_vector(&t);

  if (resultIsStatic)

we disambiguate the call against the load via modref data.  The call summary
for early modref at -O1 is

  loads:
      Base 0: alias set 0
        Ref 0: alias set 0
          access: Parm 0 param offset:0 offset:0 size:64 max_size:64
  stores:
    Every base
  Global memory written
  parm 0 flags: no_direct_clobber no_indirect_clobber no_direct_escape
no_indirect_escape no_indirect_read

where obviously no_{indirect,}_clobber isn't correct(?).  Note this seems
to result in PTA computing a stmt call clobber set that's

$20 = {anything = 0, nonlocal = 1, escaped = 1, ipa_escaped = 0, null = 0, 
  const_pool = 0, vars_contains_nonlocal = 0, vars_contains_escaped = 0, 
  vars_contains_escaped_heap = 0, vars_contains_restrict = 0, 
  vars_contains_interposable = 0, vars = 0x7ffff71b7b80}

which relies on us having 't' as escaped, but it's not (due to modref).

While modref analysis doesn't do the disambiguation the last resort check
of the call clobber set does.  In particular we create constaints:

t = &resultIsStatic
callescape(12) = &NONLOCAL
CALLUSED(13) = callescape(12)
callarg(15) = &t
callarg(15) = callarg(15) + UNKNOWN
CALLUSED(13) = callarg(15)
resultIsStatic.0_1 = resultIsStatic

so points-to doesn't consider anything call clobbered or escaped.

In particular this looks at gimpl_call_arg_flags which is computed to
EAF_NO_INDIRECT_READ | EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE
| EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER which again is wrong
since indirect clobber should be here.

I think the analysis of map_to_vector goes wrong:

 - Analyzing store: t
   - Read-only or local, ignoring.
 - Analyzing load: *F_2(D)
   - Recording base_set=0 ref_set=0  Parm 0 param offset:0 offset:0 size:64
max_size:64
 - Analyzing call:t = map_iterator (*F_2(D));
 - ECF_CONST | ECF_NOVOPS, ignoring all stores and all loads except for args.
^^^^
 - Analyzing call:ff (&t.F);
 - Merging side effects of ff/0
   Parm map: -5
 - Analyzing store: t
   - Read-only or local, ignoring.

missing that the t = map_iterator stmt copies *F to t, making t to contain
references to non-local vars which ff indirectly clobbers.


Honza?

Reply via email to