aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/ipa-inline-analysis.c6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr65655.C51
4 files changed, 67 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f744674..5a52701 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2015-04-03 Jan Hubicka <hubicka@ucw.cz>
+ PR ipa/65655
+ * ipa-inline-analysis.c (edge_set_predicate): Do not redirect
+ speculative indirect edges to avoid ordering issue.
+
+2015-04-03 Jan Hubicka <hubicka@ucw.cz>
+
PR ipa/65076
* ipa-inline.c (edge_badness): Add combined size to the denominator.
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 2f4eb9f..5d99887 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -793,7 +793,11 @@ edge_set_predicate (struct cgraph_edge *e, struct predicate *predicate)
{
/* If the edge is determined to be never executed, redirect it
to BUILTIN_UNREACHABLE to save inliner from inlining into it. */
- if (predicate && false_predicate_p (predicate))
+ if (predicate && false_predicate_p (predicate)
+ /* When handling speculative edges, we need to do the redirection
+ just once. Do it always on the direct edge, so we do not
+ attempt to resolve speculation while duplicating the edge. */
+ && (!e->speculative || e->callee))
e = redirect_to_unreachable (e);
struct inline_edge_summary *es = inline_edge_summary (e);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3e87768..09d6bd9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-04-03 Jan Hubicka <hubicka@ucw.cz>
+
+ PR ipa/65655
+ * g++.dg/torture/pr65655.C: New testcase.
+
2015-04-03 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/64085
diff --git a/gcc/testsuite/g++.dg/torture/pr65655.C b/gcc/testsuite/g++.dg/torture/pr65655.C
new file mode 100644
index 0000000..7db385d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr65655.C
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+// { dg-additional-options "-std=c++11 -fsanitize=undefined -O2" }
+class ECoordinate { };
+class EPoint {
+public:
+ inline ECoordinate & y ();
+};
+ECoordinate & EPoint::y () { }
+template < class KEY, class CONTENT > class AVLTree;
+template < class KEY, class CONTENT > class AVLTreeNode {
+ friend class
+ AVLTree < KEY, CONTENT >;
+ KEY key;
+ void set_rthread (unsigned char b);
+ void set_lthread (unsigned char b);
+};
+template < class KEY, class CONTENT > class AVLTree {
+public:
+ AVLTree ();
+ void insert (const KEY & key, const CONTENT & c);
+AVLTreeNode < KEY, CONTENT > *root;
+ const KEY * _target_key;
+ virtual int compare (const KEY & k1, const KEY & k2) const;
+ void _add (AVLTreeNode < KEY, CONTENT > *&t);
+ virtual void _status (unsigned int) { }
+};
+template < class KEY, class CONTENT > void AVLTree < KEY, CONTENT >::_add (AVLTreeNode < KEY, CONTENT > *&t) {
+ int cmp = compare (*_target_key, t->key);
+ if (cmp == 0)
+ { _status (1); }
+}
+template < class KEY, class CONTENT > void AVLTree < KEY, CONTENT >::insert (const KEY & key, const CONTENT & c) {
+ if (root == 0) {
+ root->set_rthread (1);
+ root->set_lthread (1);
+ }
+else { _target_key = &key; _add (root); }
+}
+template < class KEY, class CONTENT > AVLTree < KEY, CONTENT >::AVLTree ()
+: root (0) { }
+class ContactRepository {
+ void insertContact (EPoint & pt, int val);
+};
+void ContactRepository::insertContact (EPoint & pt, int val) {
+ AVLTreeNode < ECoordinate, AVLTree < ECoordinate, int >*>*cont_x_node;
+ if (cont_x_node == __null)
+ {
+ AVLTree < ECoordinate, int >*insert_tree = new AVLTree < ECoordinate, int >;
+ insert_tree->insert (pt.y (), val);
+ }
+}