https://gcc.gnu.org/g:9e4c57f7a69d7060612c83867ecff61a719b97af

commit r15-7685-g9e4c57f7a69d7060612c83867ecff61a719b97af
Author: Richard Biener <rguent...@suse.de>
Date:   Mon Feb 24 09:45:28 2025 +0100

    tree-optimization/118973 - stray abnormal edge after DCE
    
    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.
    
            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.

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

diff --git a/gcc/testsuite/g++.dg/torture/pr118973.C 
b/gcc/testsuite/g++.dg/torture/pr118973.C
new file mode 100644
index 000000000000..8cb9e4b023a7
--- /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 be21a2d0b507..18af81866b7e 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;

Reply via email to