Check that clones of edges exist during IPA-CP
authorMartin Jambor <mjambor@suse.cz>
Fri, 20 Apr 2018 09:19:39 +0000 (11:19 +0200)
committerMartin Jambor <jamborm@gcc.gnu.org>
Fri, 20 Apr 2018 09:19:39 +0000 (11:19 +0200)
2018-04-20  Martin Jambor  <mjambor@suse.cz>

ipa/85447
* ipa-cp.c (create_specialized_node): Check that clones of
self-recursive edges exist during IPA-CP.

testsuite/
* g++.dg/ipa/pr85447.C: New file.
* gcc.dg/ipa/ipcp-self-recursion-1.c: Likewise.

From-SVN: r259517

gcc/ChangeLog
gcc/ipa-cp.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/pr85447.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/ipa/ipcp-self-recursion-1.c [new file with mode: 0644]

index f94a904407dc7708fa8c76504f3b9e2e8e052005..a2441991818e949abaeaa9386b8df81044e36a89 100644 (file)
@@ -1,3 +1,9 @@
+2018-04-20  Martin Jambor  <mjambor@suse.cz>
+
+       ipa/85447
+       * ipa-cp.c (create_specialized_node): Check that clones of
+       self-recursive edges exist during IPA-CP.
+
 2018-04-19  Toon Moene  <toon@moene.org>
 
        * doc/invoke.texi: Add -floop-unroll-and-jam to options enabled
index 4e0e20af409e305be540491fe868aad87852de12..9388482bbeae69af551c5914a64ec05aed559ffb 100644 (file)
@@ -3867,9 +3867,17 @@ create_specialized_node (struct cgraph_node *node,
   for (unsigned j = 0; j < self_recursive_calls.length (); j++)
     {
       cgraph_edge *cs = next_edge_clone[self_recursive_calls[j]->uid];
-      gcc_checking_assert (cs);
-      gcc_assert (cs->caller == new_node);
-      cs->redirect_callee_duplicating_thunks (new_node);
+      /* Cloned edges can disappear during cloning as speculation can be
+        resolved, check that we have one and that it comes from the last
+        cloning.  */
+      if (cs && cs->caller == new_node)
+       cs->redirect_callee_duplicating_thunks (new_node);
+      /* Any future code that would make more than one clone of an outgoing
+        edge would confuse this mechanism, so let's check that does not
+        happen.  */
+      gcc_checking_assert (!cs
+                          || !next_edge_clone[cs->uid]
+                          || next_edge_clone[cs->uid]->caller != new_node);
     }
   if (have_self_recursive_calls)
     new_node->expand_all_artificial_thunks ();
index 3450e1dca70bf8f3d9ed1a13e18c719cb530a9e3..92b40feafdf8b76a0e72bc66653c08a62c11935d 100644 (file)
@@ -1,3 +1,9 @@
+2018-04-20  Martin Jambor  <mjambor@suse.cz>
+
+       ipa/85447
+       * g++.dg/ipa/pr85447.C: New file.
+       * gcc.dg/ipa/ipcp-self-recursion-1.c: Likewise.
+
 2018-04-20  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/85462
diff --git a/gcc/testsuite/g++.dg/ipa/pr85447.C b/gcc/testsuite/g++.dg/ipa/pr85447.C
new file mode 100644 (file)
index 0000000..d7a7716
--- /dev/null
@@ -0,0 +1,23 @@
+// { dg-do compile }
+// { dg-options "-O3 -std=gnu++11" }
+
+typedef int a;
+enum b : a;
+class c {
+public:
+  enum { d };
+  virtual b e(int *, int, const int *) = 0;
+};
+class f : c {
+  b e(int *, int, const int *);
+  b g();
+};
+b f::e(int *h, int i, const int *j) {
+  if (i == d)
+    return g();
+  for (;;)
+    e(h, i, j);
+}
+int k;
+c *l;
+void m() { l->e(&k, c::d, nullptr); }
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-self-recursion-1.c b/gcc/testsuite/gcc.dg/ipa/ipcp-self-recursion-1.c
new file mode 100644 (file)
index 0000000..7ecbf79
--- /dev/null
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fno-early-inlining"  } */
+
+int array[128];
+
+volatile int v = 0;
+volatile int blah = 0;
+volatile int counter = 0;
+
+int __attribute__((noipa))
+obscured_one ()
+{
+  return 1;
+}
+
+static void
+f (int c, int l)
+{
+  int i;
+  for (i = 0; i < c; i++)
+    array[i] = 455;
+
+  counter++;
+  if (counter > 6)
+    __builtin_abort ();
+
+  v = l;
+  if (l > 0)
+    f (c, l - 1);
+  blah = l;
+}
+
+int
+main (int argc, char *argv[])
+{
+  int i;
+  for (i = 0; i < 100; i++)
+    {
+      counter = 0;
+      f (0, 5);
+      if (obscured_one ())
+       break;
+    }
+
+  return 0;
+}