This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix up gimple cross-jumping (PR tree-optimization/71643)


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  <jakub@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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]