Hi!

My recent change to handle labels (other than forced/non-local) caused
ICE on the following testcase, I thought EH pads would always differ with
the special stuff in them for each region, but with __builtin_unreachable
we can end up with the same bbs, which EH edge redirection isn't able to
cope with though.

So, the following patch disables cross-jumping of bbs with EH incoming
edges (we weren't allowing that before either, because those need to have
some labels at the start and those were always unique to each bb).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2016-06-24  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/71643
        * tree-ssa-tail-merge.c (find_clusters_1): Ignore basic blocks with
        EH preds.

        * tree-ssa-tail-merge.c (deps_ok_for_redirect_from_bb_to_bb): Don't
        leak a bitmap if dep_bb is NULL.

        * g++.dg/opt/pr71643.C: New test.

--- gcc/tree-ssa-tail-merge.c.jj        2016-06-14 12:18:31.000000000 +0200
+++ gcc/tree-ssa-tail-merge.c   2016-06-24 14:25:37.901398826 +0200
@@ -1398,11 +1398,11 @@ deps_ok_for_redirect_from_bb_to_bb (basi
   basic_block cd, dep_bb = BB_DEP_BB (to);
   edge_iterator ei;
   edge e;
-  bitmap from_preds = BITMAP_ALLOC (NULL);
 
   if (dep_bb == NULL)
     return true;
 
+  bitmap from_preds = BITMAP_ALLOC (NULL);
   FOR_EACH_EDGE (e, ei, from->preds)
     bitmap_set_bit (from_preds, e->src->index);
   cd = nearest_common_dominator_for_set (CDI_DOMINATORS, from_preds);
@@ -1446,7 +1446,7 @@ find_clusters_1 (same_succ *same_succ)
       /* TODO: handle blocks with phi-nodes.  We'll have to find corresponding
         phi-nodes in bb1 and bb2, with the same alternatives for the same
         preds.  */
-      if (bb_has_non_vop_phi (bb1))
+      if (bb_has_non_vop_phi (bb1) || bb_has_eh_pred (bb1))
        continue;
 
       nr_comparisons = 0;
@@ -1454,7 +1454,7 @@ find_clusters_1 (same_succ *same_succ)
        {
          bb2 = BASIC_BLOCK_FOR_FN (cfun, j);
 
-         if (bb_has_non_vop_phi (bb2))
+         if (bb_has_non_vop_phi (bb2) || bb_has_eh_pred (bb2))
            continue;
 
          if (BB_CLUSTER (bb1) != NULL && BB_CLUSTER (bb1) == BB_CLUSTER (bb2))
--- gcc/testsuite/g++.dg/opt/pr71643.C.jj       2016-06-24 14:21:09.572703177 
+0200
+++ gcc/testsuite/g++.dg/opt/pr71643.C  2016-06-24 14:20:55.000000000 +0200
@@ -0,0 +1,20 @@
+// PR tree-optimization/71643
+// { dg-do compile }
+// { dg-options "-O2" }
+
+struct A
+{
+  void *operator new (__SIZE_TYPE__, unsigned);
+  void operator delete (void *, unsigned) { __builtin_unreachable (); }
+  A (int x);
+  static A *bar (int x) { return new (3) A (x); }
+};
+void baz (A *, A *);
+
+void
+foo (int a, int b)
+{
+  A *p = A::bar (a);
+  A *q = A::bar (b);
+  baz (p, q);
+}

        Jakub

Reply via email to