aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2018-04-20 11:19:39 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2018-04-20 11:19:39 +0200
commit5fc1b92025fa55f6de9f93bf02df424a17802e55 (patch)
tree5446541e8d006b47acfa69a5dc29b904ff97bf8d
parente00e62761dbd91200af4e448ff13b598d918049f (diff)
downloadgcc-5fc1b92025fa55f6de9f93bf02df424a17802e55.zip
gcc-5fc1b92025fa55f6de9f93bf02df424a17802e55.tar.gz
gcc-5fc1b92025fa55f6de9f93bf02df424a17802e55.tar.bz2
Check that clones of edges exist during IPA-CP
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/ipa-cp.c14
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr85447.C23
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-self-recursion-1.c46
5 files changed, 92 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f94a904..a244199 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 4e0e20a..9388482 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -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 ();
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3450e1d..92b40fe 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..d7a7716
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr85447.C
@@ -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
index 0000000..7ecbf79
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-self-recursion-1.c
@@ -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;
+}