diff options
author | Marek Polacek <polacek@redhat.com> | 2012-12-02 20:16:09 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2012-12-02 20:16:09 +0000 |
commit | 60cec1fd88bb0922387cd06d381fc73230a50fd6 (patch) | |
tree | 994e3f067e69fffac35076de32d2c1530f1af0a2 /gcc | |
parent | bde8c9629a161f292ba1d9c97c28e7cd61806eb9 (diff) | |
download | gcc-60cec1fd88bb0922387cd06d381fc73230a50fd6.zip gcc-60cec1fd88bb0922387cd06d381fc73230a50fd6.tar.gz gcc-60cec1fd88bb0922387cd06d381fc73230a50fd6.tar.bz2 |
re PR middle-end/54838 (ICE: in merge_latch_edges, at cfgloop.c:678 with -ftracer)
PR54838
From-SVN: r194060
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cprop.c | 29 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr54838.c | 24 |
4 files changed, 57 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6ba71f1..18c930c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-12-02 Marek Polacek <polacek@redhat.com> + + PR middle-end/54838 + * cprop.c (bypass_block): Determine number of latches. Return + when there is more than one latch edge. + 2012-12-02 Teresa Johnson <tejohnson@google.com> PR gcov-profile/55551 diff --git a/gcc/cprop.c b/gcc/cprop.c index 3fb266a..ec896a4 100644 --- a/gcc/cprop.c +++ b/gcc/cprop.c @@ -1510,13 +1510,28 @@ bypass_block (basic_block bb, rtx setcc, rtx jump) if (note) find_used_regs (&XEXP (note, 0), NULL); - may_be_loop_header = false; - FOR_EACH_EDGE (e, ei, bb->preds) - if (e->flags & EDGE_DFS_BACK) - { - may_be_loop_header = true; - break; - } + /* Determine whether there are more latch edges. Threading through + a loop header with more than one latch is delicate, see e.g. + tree-ssa-threadupdate.c:thread_through_loop_header. */ + if (current_loops) + { + may_be_loop_header = bb == bb->loop_father->header; + if (may_be_loop_header + && bb->loop_father->latch == NULL) + return 0; + } + else + { + unsigned n_back_edges = 0; + FOR_EACH_EDGE (e, ei, bb->preds) + if (e->flags & EDGE_DFS_BACK) + n_back_edges++; + + may_be_loop_header = n_back_edges > 0; + + if (n_back_edges > 1) + return 0; + } change = 0; for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); ) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3103cf1..981d0d1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-12-02 Marek Polacek <polacek@redhat.com> + + PR middle-end/54838 + * gcc.dg/pr54838.c: New test. + 2012-12-01 Xinliang David Li <davidxl@google.com> * gcc.target/i386/ifcvt-onecmpl-abs-1.c: Check for diff --git a/gcc/testsuite/gcc.dg/pr54838.c b/gcc/testsuite/gcc.dg/pr54838.c new file mode 100644 index 0000000..9ed92f9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr54838.c @@ -0,0 +1,24 @@ +/* PR middle-end/54838 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-forward-propagate -ftracer" } */ + +void bar (void); + +void +foo (void *b, int *c) +{ +again: + switch (*c) + { + case 1: + if (!b) + { + bar (); + return; + } + goto again; + case 3: + if (!b) + goto again; + } +} |