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

Reply via email to