re PR ipa/65655 (ICE in speculative_call_info, at cgraph.c:1151)
authorJan Hubicka <hubicka@ucw.cz>
Fri, 3 Apr 2015 18:19:53 +0000 (20:19 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 3 Apr 2015 18:19:53 +0000 (18:19 +0000)
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.

From-SVN: r221860

gcc/ChangeLog
gcc/ipa-inline-analysis.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr65655.C [new file with mode: 0644]

index f744674c4d16ce580c14753e404cd1546ec36541..5a52701eebf46589237a555dcdea0d50c27646f0 100644 (file)
@@ -1,3 +1,9 @@
+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
index 2f4eb9fd6f2337815265ab4b1988346f4a0eac01..5d998870f346e66a506a82c87a929b97cc0e047d 100644 (file)
@@ -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);
index 3e87768625a4da8854c0632a331013ebca834e87..09d6bd943e56ba20f11863e50db88e3ec7851780 100644 (file)
@@ -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 (file)
index 0000000..7db385d
--- /dev/null
@@ -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);
+    }
+}