Hi,
this patch fixes ordering issue where we try to resolve speculation while
we are mid of its duplication.
Bootstrapped/regtested x86_64-liinux, will commit it shortly.
Honza
PR ipa/65655
* ipa-inline-analysis.c (edge_set_predicate): Do not redirect
speculative indirect edges to avoid ordering issue.
* g++.dg/torture/pr65655.C: New testcase.
Index: ipa-inline-analysis.c
===================================================================
--- ipa-inline-analysis.c (revision 221845)
+++ ipa-inline-analysis.c (working copy)
@@ -793,7 +793,11 @@ edge_set_predicate (struct cgraph_edge *
{
/* 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);
Index: testsuite/g++.dg/torture/pr65655.C
===================================================================
--- testsuite/g++.dg/torture/pr65655.C (revision 0)
+++ testsuite/g++.dg/torture/pr65655.C (working copy)
@@ -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);
+ }
+}