On Sun, Aug 22, 2021 at 7:32 PM Jan Hubicka <hubi...@ucw.cz> wrote: > > > Thanks for looking into this bug - it is interesting that ipa-pta > > requires !EAF_NOCLOBBER when function is called... > > > > I have some work done on teaching ipa-modref (and other propagation > > passes) to use ipa-devirt info when the full set of callees is known. > > This goes oposite way. > > > > You can drop flags only when callee == NAME and you can just frop > > EAF_NOCLOBBER. For example in testcase > > > > struct a { > > void (*foo)(); > > void *bar; > > } > > > > void wrap (struct a *a) > > { > > a->foo (); > > } > > > > will prevent us from figuring out that bar can not be modified when you > > pass non-ecaping instance of struct a to wrap. > > > > I am testing this updated patch which implements that. I am not very > happy about this (it punishes -fno-ipa-pta path for not very good > reason), but we need bugfix for release branch.
Why does it "punish" -fno-ipa-pta? It merely "punishes" modref of no longer claiming that we do not alter the instruction stream pointed to by a->foo, sth that shouldn't be very common. Note that IPA PTA doesn't really know whether the passed argument is a function or not, also 'wrap' could just receive a void * pointer and still call the function. So we're very much relying on how this all plays out ... > It is very easy now to add now EAF flags at modref side > so we can track EAF_NOT_CALLED. > tree-ssa-structalias side is always bit anoying wrt new EAF flags > because it has three copies of the code building constraints for call > (for normal, pure and const). > > Modref is already tracking if function can read/modify global memory. I > plan to add flags for NRC and link chain and then we can represent > effect of ECF_CONST and PURE by simply adding flags. I would thus would > like to merge that code. We do various optimizations to reduce amount > of constriants produced, but hopefully this is not very important (or > can be implemented by special casing in unified code). > > Honza > > gcc/ChangeLog: > > 2021-08-22 Jan Hubicka <hubi...@ucw.cz> > Martin Liska <mli...@suse.cz> > > * ipa-modref.c (analyze_ssa_name_flags): Indirect call implies > ~EAF_NOCLOBBER. > > gcc/testsuite/ChangeLog: > > 2021-08-22 Jan Hubicka <hubi...@ucw.cz> > Martin Liska <mli...@suse.cz> > > * gcc.dg/lto/pr101949_0.c: New test. > * gcc.dg/lto/pr101949_1.c: New test. > > diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c > index fafd804d4ba..549153865b8 100644 > --- a/gcc/ipa-modref.c > +++ b/gcc/ipa-modref.c > @@ -1700,6 +1700,15 @@ analyze_ssa_name_flags (tree name, vec<modref_lattice> > &lattice, int depth, > else if (gcall *call = dyn_cast <gcall *> (use_stmt)) > { > tree callee = gimple_call_fndecl (call); > + > + /* IPA PTA internally it treats calling a function as "writing" to > + the argument space of all functions the function pointer points > to > + (PR101949). We can not drop EAF_NOCLOBBER only when ipa-pta > + is on since that would allow propagation of this from > -fno-ipa-pta > + to -fipa-pta functions. */ > + if (gimple_call_fn (use_stmt) == name) > + lattice[index].merge (~EAF_NOCLOBBER); > + > /* Return slot optimization would require bit of propagation; > give up for now. */ > if (gimple_call_return_slot_opt_p (call) > diff --git a/gcc/testsuite/gcc.dg/lto/pr101949_0.c > b/gcc/testsuite/gcc.dg/lto/pr101949_0.c > new file mode 100644 > index 00000000000..142dffe8780 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/lto/pr101949_0.c > @@ -0,0 +1,20 @@ > +/* { dg-lto-do run } */ > +/* { dg-lto-options { "-O2 -fipa-pta -flto -flto-partition=1to1" } } */ > + > +extern int bar (int (*)(int *), int *); > + > +static int x; > + > +static int __attribute__ ((noinline)) foo (int *p) > +{ > + *p = 1; > + x = 0; > + return *p; > +} > + > +int main () > +{ > + if (bar (foo, &x) != 0) > + __builtin_abort (); > + return 0; > +} > diff --git a/gcc/testsuite/gcc.dg/lto/pr101949_1.c > b/gcc/testsuite/gcc.dg/lto/pr101949_1.c > new file mode 100644 > index 00000000000..871d15c9bfb > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/lto/pr101949_1.c > @@ -0,0 +1,4 @@ > +int __attribute__((noinline,noclone)) bar (int (*fn)(int *), int *p) > +{ > + return fn (p); > +}