summaryrefslogtreecommitdiff
path: root/gcc/ipa-split.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2015-12-01 11:35:21 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2015-12-01 11:35:21 +0000
commitece95567dfbaff5b3e2fb8ca3552e0c086757cc7 (patch)
tree72395cfafea030c54b997608b50b52b4de55ba77 /gcc/ipa-split.c
parent22f5095f313a7a4ed676ac22bb3fde16eb172a39 (diff)
downloadgcc-ece95567dfbaff5b3e2fb8ca3552e0c086757cc7.tar.gz
re PR ipa/68470 (Internal Compiler Error observed by g++-4.9.2 and a few other versions (reported to Debian))
2015-12-01 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. From-SVN: r231108
Diffstat (limited to 'gcc/ipa-split.c')
-rw-r--r--gcc/ipa-split.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index be33ddae412..56c954b01b2 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -1205,7 +1205,6 @@ split_function (basic_block return_bb, struct split_point *split_point,
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,28 @@ split_function (basic_block return_bb, struct split_point *split_point,
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;
+ }
+ /* The main part also returns if we we split on a fallthru edge
+ and the split part returns. */
+ if (split_part_return_p)
+ FOR_EACH_EDGE (e, ei, split_point->entry_bb->preds)
+ {
+ if (! bitmap_bit_p (split_point->split_bbs, e->src->index)
+ && single_succ_p (e->src))
+ {
+ main_part_return_p = true;
+ break;
+ }
+ }
/* Add return block to what will become the split function.
We do not return; no return block is needed. */
@@ -1295,6 +1310,11 @@ split_function (basic_block return_bb, struct split_point *split_point,
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.