]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/118973 - stray abnormal edge after DCE
authorRichard Biener <rguenther@suse.de>
Mon, 24 Feb 2025 08:45:28 +0000 (09:45 +0100)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 24 Feb 2025 10:11:54 +0000 (11:11 +0100)
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.

gcc/testsuite/g++.dg/torture/pr118973.C [new file with mode: 0644]
gcc/tree-ssa-dce.cc

diff --git a/gcc/testsuite/g++.dg/torture/pr118973.C b/gcc/testsuite/g++.dg/torture/pr118973.C
new file mode 100644 (file)
index 0000000..8cb9e4b
--- /dev/null
@@ -0,0 +1,10 @@
+// { dg-do compile }
+
+int foo() __attribute__((returns_twice));
+
+void a()
+{
+  int a;
+  if(foo()) new int;
+  &a;
+}
index be21a2d0b507e4f325ecdec2100aecab74fa68f9..18af81866b7eaf00b16bedde676f48430cca1c84 100644 (file)
@@ -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;