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?