diff mbox

Fix PR68470, ICE in IPA split

Message ID alpine.LSU.2.11.1511271032540.4884@t29.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Nov. 27, 2015, 9:36 a.m. UTC
This fixes the case where we split the returning part of a function
and keep the non-returning part as main.  We were keeping the return
block with stmts not relevant to main in the return path of the
split which obviously doesn't work as it may use SSA names no longer
defined (but split out).

The following patch detects the situation and pretends the exit
block was found as EXIT_BLOCK_FOR_FN in this case.

Bootstrap and regtest ongoing on x86_64-unknown-linux-gnu.

Honza, does this look ok?

Thanks,
Richard.

2015-11-27  Richard Biener  <rguenther@suse.de>

	PR ipa/68470
	* ipa-split.c (split_function): Handle main part not returning.

	* g++.dg/torture/pr68470.C: New testcase.
diff mbox

Patch

Index: gcc/ipa-split.c
===================================================================
--- gcc/ipa-split.c	(revision 230998)
+++ gcc/ipa-split.c	(working copy)
@@ -1205,7 +1205,6 @@  split_function (basic_block return_bb, s
   edge e;
   edge_iterator ei;
   tree retval = NULL, real_retval = NULL, retbnd = NULL;
-  bool split_part_return_p = false;
   bool with_bounds = chkp_function_instrumented_p (current_function_decl);
   gimple *last_stmt = NULL;
   unsigned int i;
@@ -1246,12 +1245,16 @@  split_function (basic_block return_bb, s
 	args_to_pass.safe_push (arg);
       }
 
-  /* See if the split function will return.  */
+  /* See if the split function or the main part will return.  */
+  bool main_part_return_p = false;
+  bool split_part_return_p = false;
   FOR_EACH_EDGE (e, ei, return_bb->preds)
-    if (bitmap_bit_p (split_point->split_bbs, e->src->index))
-      break;
-  if (e)
-    split_part_return_p = true;
+    {
+      if (bitmap_bit_p (split_point->split_bbs, e->src->index))
+	split_part_return_p = true;
+      else
+	main_part_return_p = true;
+    }
 
   /* Add return block to what will become the split function.
      We do not return; no return block is needed.  */
@@ -1295,6 +1298,11 @@  split_function (basic_block return_bb, s
   else
     bitmap_set_bit (split_point->split_bbs, return_bb->index);
 
+  /* If the main part doesn't return pretend the return block wasn't
+     found for all of the following.  */
+  if (! main_part_return_p)
+    return_bb = EXIT_BLOCK_PTR_FOR_FN (cfun);
+
   /* If RETURN_BB has virtual operand PHIs, they must be removed and the
      virtual operand marked for renaming as we change the CFG in a way that
      tree-inline is not able to compensate for.
Index: gcc/testsuite/g++.dg/torture/pr68470.C
===================================================================
--- gcc/testsuite/g++.dg/torture/pr68470.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/pr68470.C	(working copy)
@@ -0,0 +1,36 @@ 
+/* { dg-do compile } */
+
+void deallocate(void *);
+void *a;
+
+struct C {
+    virtual void m_fn1();
+};
+
+struct D {
+    C *m_fn2() {
+	if (a)
+	  __builtin_abort();
+    }
+};
+D getd();
+
+struct vec_int {
+    int _M_start;
+    ~vec_int() {
+	if (_M_start)
+	  deallocate(&_M_start);
+    }
+};
+vec_int *b;
+
+struct I {
+    virtual void m_fn3();
+};
+
+void I::m_fn3() {
+    if (a)
+      getd().m_fn2()->m_fn1();
+    b->~vec_int();
+}
+