When forwprop discovers unreachable code or makes decisions based on unreachable edges make sure to cleanup the CFG since otherwise SSA form can become invalid.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. PR tree-optimization/109331 * tree-ssa-forwprop.cc (pass_forwprop::execute): When we discover a taken edge make sure to cleanup the CFG. * gcc.dg/torture/pr109331.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr109331.c | 16 ++++++++++++++++ gcc/tree-ssa-forwprop.cc | 6 +++++- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr109331.c diff --git a/gcc/testsuite/gcc.dg/torture/pr109331.c b/gcc/testsuite/gcc.dg/torture/pr109331.c new file mode 100644 index 00000000000..72c57b9b74c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr109331.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +char *ustol_dpp; +void ustol(int flags) +{ + char *s; + if (s) + flags |= 3; + switch (flags & 3) + case 3: + while (*s) + case '+': + ++s; + if (flags) + ustol_dpp = s; +} diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc index bb0fa306312..9b567440ba4 100644 --- a/gcc/tree-ssa-forwprop.cc +++ b/gcc/tree-ssa-forwprop.cc @@ -4046,7 +4046,11 @@ pass_forwprop::execute (function *fun) /* Mark outgoing exectuable edges. */ if (edge e = find_taken_edge (bb, NULL)) - e->flags |= EDGE_EXECUTABLE; + { + e->flags |= EDGE_EXECUTABLE; + if (EDGE_COUNT (bb->succs) > 1) + cfg_changed = true; + } else { FOR_EACH_EDGE (e, ei, bb->succs) -- 2.35.3