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);
+    }
+}

Reply via email to