]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Clear EAF_NOCLOBBER for indirect calls
authorJan Hubicka <jh@suse.cz>
Sun, 22 Aug 2021 18:57:19 +0000 (20:57 +0200)
committerJan Hubicka <jh@suse.cz>
Sun, 22 Aug 2021 18:57:19 +0000 (20:57 +0200)
gcc/ChangeLog:

2021-08-22  Jan Hubicka  <hubicka@ucw.cz>
    Martin Liska  <mliska@suse.cz>

PR middle-end/101949
* 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.

gcc/ipa-modref.c
gcc/testsuite/gcc.dg/lto/pr101949_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/pr101949_1.c [new file with mode: 0644]

index fafd804d4bae453198bd9f5f38916ef3aeb50d3a..549153865b80f501a5521ddb4ac5bee9236c0cb1 100644 (file)
@@ -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 (file)
index 0000000..142dffe
--- /dev/null
@@ -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 (file)
index 0000000..871d15c
--- /dev/null
@@ -0,0 +1,4 @@
+int __attribute__((noinline,noclone)) bar (int (*fn)(int *), int *p)
+{
+  return fn (p);
+}