From eabec4d3c56af2e8959c8329b5257a81c606da60 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Fri, 23 Nov 2018 23:51:26 -0700 Subject: [PATCH] re PR rtl-optimization/87468 (ice "wrong amount of branch edges after conditional jump in bb") PR rtl-optimization/87468 * tree-ssa-threadupdate.c (create_block_for_threading): Clear EDGE_IGNORE on all outgoing edges of the duplicate block. From-SVN: r266426 --- gcc/ChangeLog | 6 ++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.c-torture/compile/pr87468.c | 15 +++++++++++++++ gcc/tree-ssa-threadupdate.c | 12 +++++++++++- 4 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr87468.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b0b85bac352..f9a12f88a60 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-11-23 Jeff Law + + PR rtl-optimization/87468 + * tree-ssa-threadupdate.c (create_block_for_threading): Clear + EDGE_IGNORE on all outgoing edges of the duplicate block. + 2018-11-23 Vladimir Makarov PR bootstrap/88157 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e31d40d7924..587526e7443 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-11-23 Jeff Law + + PR rtl-optimization/84768 + * gcc.c-torture/compile/pr84768.c: New test. + 2018-11-23 Vladimir Makarov * gcc.target/powerpc/pr70669.c: Use unary minus instead of diff --git a/gcc/testsuite/gcc.c-torture/compile/pr87468.c b/gcc/testsuite/gcc.c-torture/compile/pr87468.c new file mode 100644 index 00000000000..2f5cf80bf9f --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr87468.c @@ -0,0 +1,15 @@ +a; +b() { + int c = 1; + for (; c <= 3;) { + int d = e() && !0; + switch (c) + case 1: + if (d) + case 2: + case 3: + f(); + if (a) + c++; + } +} diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index 6630516b99a..e7c7ca6fb15 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -336,7 +336,17 @@ create_block_for_threading (basic_block bb, rd->dup_blocks[count] = duplicate_block (bb, NULL, NULL); FOR_EACH_EDGE (e, ei, rd->dup_blocks[count]->succs) - e->aux = NULL; + { + e->aux = NULL; + + /* If we duplicate a block with an outgoing edge marked as + EDGE_IGNORE, we must clear EDGE_IGNORE so that it doesn't + leak out of the current pass. + + It would be better to simplify switch statements and remove + the edges before we get here, but the sequencing is nontrivial. */ + e->flags &= ~EDGE_IGNORE; + } /* Zero out the profile, since the block is unreachable for now. */ rd->dup_blocks[count]->count = profile_count::uninitialized (); -- 2.30.2