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  <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);
+}


Reply via email to