[PATCH] IPA: MODREF should skip EAF_* flags for indirect calls

Martin Liška mliska@suse.cz
Mon Aug 23 07:53:46 GMT 2021


On 8/22/21 19:32, Jan Hubicka 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.

Hello.

Thanks for working on that. But have really run the test-cases as the newly
added test still aborts as it used to before you installed this patch?

Martin

> 
> 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  <hubicka@ucw.cz>
> 	    Martin Liska  <mliska@suse.cz>
> 
> 	* ipa-modref.c (analyze_ssa_name_flags): Indirect call implies
> 	~EAF_NOCLOBBER.
> 
> gcc/testsuite/ChangeLog:
> 
> 2021-08-22  Jan Hubicka  <hubicka@ucw.cz>
> 	    Martin Liska  <mliska@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);
> +}
> 



More information about the Gcc-patches mailing list