DCE preserves stmts performing abnormal control flow transfer but
currently has an exception for replaceable allocations and cxa_atexit
calls.  That results in a broken CFG since DCE isn't set up to prune
abnormal edges possibly hanging off those.

While we could try to add this handling, the following is the safe
fix at this point and more suitable for backporting.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

        PR tree-optimization/118973
        * tree-ssa-dce.cc (mark_stmt_if_obviously_necessary): Calls
        that alter control flow in unpredictable ways need to be
        preserved.

        * g++.dg/torture/pr118973.C: New testcase.
---
 gcc/testsuite/g++.dg/torture/pr118973.C | 10 ++++++++++
 gcc/tree-ssa-dce.cc                     |  8 ++++----
 2 files changed, 14 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/torture/pr118973.C

diff --git a/gcc/testsuite/g++.dg/torture/pr118973.C 
b/gcc/testsuite/g++.dg/torture/pr118973.C
new file mode 100644
index 00000000000..8cb9e4b023a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr118973.C
@@ -0,0 +1,10 @@
+// { dg-do compile }
+
+int foo() __attribute__((returns_twice));
+
+void a()
+{
+  int a;
+  if(foo()) new int;
+  &a;
+}
diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc
index 461283ba858..ba9cd6536ae 100644
--- a/gcc/tree-ssa-dce.cc
+++ b/gcc/tree-ssa-dce.cc
@@ -391,15 +391,15 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool 
aggressive)
       {
        gcall *call = as_a <gcall *> (stmt);
 
-       /* Never elide a noreturn call we pruned control-flow for.  */
-       if ((gimple_call_flags (call) & ECF_NORETURN)
-           && gimple_call_ctrl_altering_p (call))
+       /* Never elide a noreturn call we pruned control-flow for.
+          Same for statements that can alter control flow in unpredictable
+          ways.  */
+       if (gimple_call_ctrl_altering_p (call))
          {
            mark_stmt_necessary (call, true);
            return;
          }
 
-
        if (is_removable_allocation_p (call, false))
          return;
 
-- 
2.43.0

Reply via email to