aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfghooks.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2012-12-20 12:45:48 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2012-12-20 12:45:48 +0000
commit63f2ff0f23d633aad769997ec617ce2177c311ec (patch)
treebe55ad20b58a1170be63f32e62e1407bc7395272 /gcc/cfghooks.c
parenteadd3d0d54b72308446ce8e615b180fe33eed36a (diff)
downloadgcc-63f2ff0f23d633aad769997ec617ce2177c311ec.zip
gcc-63f2ff0f23d633aad769997ec617ce2177c311ec.tar.gz
gcc-63f2ff0f23d633aad769997ec617ce2177c311ec.tar.bz2
re PR rtl-optimization/55740 (ICE in verify_loop_structure, at cfgloop.c:1582, error: loop 2's header does not belong directly to it)
2012-12-20 Richard Biener <rguenther@suse.de> PR middle-end/55740 * cfghooks.c (merge_blocks): Properly handle merging of two loop headers. * g++.dg/torture/pr55740.C: New testcase. From-SVN: r194633
Diffstat (limited to 'gcc/cfghooks.c')
-rw-r--r--gcc/cfghooks.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index f095731..b729ae0 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -724,11 +724,23 @@ merge_blocks (basic_block a, basic_block b)
cfg_hooks->merge_blocks (a, b);
- /* If we merge a loop header into its predecessor, update the loop
- structure. */
if (current_loops != NULL)
{
- if (b->loop_father->header == b)
+ /* If the block we merge into is a loop header do nothing unless ... */
+ if (a->loop_father->header == a)
+ {
+ /* ... we merge two loop headers, in which case we kill
+ the inner loop. */
+ if (b->loop_father->header == b)
+ {
+ b->loop_father->header = NULL;
+ b->loop_father->latch = NULL;
+ loops_state_set (LOOPS_NEED_FIXUP);
+ }
+ }
+ /* If we merge a loop header into its predecessor, update the loop
+ structure. */
+ else if (b->loop_father->header == b)
{
remove_bb_from_loops (a);
add_bb_to_loop (a, b->loop_father);