Hi! This testcase ICEs starting with the {CLOBBER} additions, because cleanup_empty_eh_merge_phis attempts to redirect an edge to a bb from a bb that already has another edge to that same destination bb. Richard fixed a similar issue last year in one of the cleanup_empty_eh_merge_phis caller's, but this time it happened from the other caller.
This patch therefore moves that check into cleanup_empty_eh_merge_phis, so that it handles it right for all callers. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2011-11-30 Jakub Jelinek <ja...@redhat.com> PR middle-end/51089 * tree-eh.c (cleanup_empty_eh_merge_phis): Add check to avoid creating duplicate edges here. (cleanup_empty_eh_unsplit): And remove it in the caller. * gfortran.dg/gomp/pr51089.f90: New test. --- gcc/tree-eh.c.jj 2011-11-29 08:58:52.000000000 +0100 +++ gcc/tree-eh.c 2011-11-30 16:13:32.395352143 +0100 @@ -3653,6 +3653,22 @@ cleanup_empty_eh_merge_phis (basic_block bitmap rename_virts; bitmap ophi_handled; + /* The destination block must not be a regular successor for any + of the preds of the landing pad. Thus, avoid turning + <..> + | \ EH + | <..> + | / + <..> + into + <..> + | | EH + <..> + which CFG verification would choke on. See PR45172 and PR51089. */ + FOR_EACH_EDGE (e, ei, old_bb->preds) + if (find_edge (e->src, new_bb)) + return false; + FOR_EACH_EDGE (e, ei, old_bb->preds) redirect_edge_var_map_clear (e); @@ -3815,8 +3831,6 @@ cleanup_empty_eh_unsplit (basic_block bb { gimple_stmt_iterator gsi; tree lab; - edge_iterator ei; - edge e; /* We really ought not have totally lost everything following a landing pad label. Given that BB is empty, there had better @@ -3839,22 +3853,6 @@ cleanup_empty_eh_unsplit (basic_block bb return false; } - /* The destination block must not be a regular successor for any - of the preds of the landing pad. Thus, avoid turning - <..> - | \ EH - | <..> - | / - <..> - into - <..> - | | EH - <..> - which CFG verification would choke on. See PR45172. */ - FOR_EACH_EDGE (e, ei, bb->preds) - if (find_edge (e->src, e_out->dest)) - return false; - /* Attempt to move the PHIs into the successor block. */ if (cleanup_empty_eh_merge_phis (e_out->dest, bb, e_out, false)) { --- gcc/testsuite/gfortran.dg/gomp/pr51089.f90.jj 2011-11-30 16:18:08.894351965 +0100 +++ gcc/testsuite/gfortran.dg/gomp/pr51089.f90 2011-11-30 16:17:44.000000000 +0100 @@ -0,0 +1,16 @@ +! PR middle-end/51089 +! { dg-do compile } +! { dg-options "-O -fexceptions -fopenmp" } + +subroutine foo + real, allocatable, dimension(:) :: s + real, dimension(:, :, :), pointer :: t + call fn1 (t, s) + call fn2 () +end subroutine foo +subroutine bar + integer :: i +!$omp parallel do + do i = 1, 10 + end do +end subroutine bar Jakub