Hi,

Zhendong Su and Michal Jireš found out that our gimple DSE pass can,
under fairly specific conditions, remove a noreturn call which then
leaves behind a "normal" BB with no successor edges which following
passes do not expect.  This patch simply tells the pass to leave such
calls alone even when they otherwise appear to be dead.

Interestingly, our CFG verifier does not report this.  I'll put on my
todo list to add a test for it in the next stage 1.

Bootstrapped and tested on x86_64-linux, OK for master?

Thanks,

Martin


gcc/ChangeLog:

2025-01-27  Martin Jambor  <mjam...@suse.cz>

        PR tree-optimization/117892
        * tree-ssa-dse.cc (dse_optimize_call): Leave noreturn calls alone.

gcc/testsuite/ChangeLog:

2025-01-27  Martin Jambor  <mjam...@suse.cz>

        PR tree-optimization/117892
        * gcc.dg/tree-ssa/pr117892.c: New test.
        * gcc.dg/tree-ssa/pr118517.c: Likewise.

co-authored-by: Michal Jireš <mji...@suse.cz>
---
 gcc/testsuite/gcc.dg/tree-ssa/pr117892.c | 17 +++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr118517.c | 11 +++++++++++
 gcc/tree-ssa-dse.cc                      |  5 +++--
 3 files changed, 31 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr117892.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr118517.c

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr117892.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr117892.c
new file mode 100644
index 00000000000..d9b9c15095f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr117892.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+
+volatile int a;
+void b(int *c) {
+  int *d = 0;
+  *c = 0;
+  *d = 0;
+  __builtin_abort();
+}
+int main() {
+  int f;
+  if (a)
+    b(&f);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr118517.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr118517.c
new file mode 100644
index 00000000000..3a34f6788a9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr118517.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fno-ipa-pure-const" } */
+
+void __attribute__((noreturn)) bar(void) {
+  __builtin_unreachable ();
+}
+
+int p;
+void foo() {
+  if (p) bar();
+}
diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc
index 753d7ef148b..492080a7eb0 100644
--- a/gcc/tree-ssa-dse.cc
+++ b/gcc/tree-ssa-dse.cc
@@ -1396,8 +1396,9 @@ dse_optimize_call (gimple_stmt_iterator *gsi, sbitmap 
live_bytes)
   if (!node)
     return false;
 
-  if (stmt_could_throw_p (cfun, stmt)
-      && !cfun->can_delete_dead_exceptions)
+  if ((stmt_could_throw_p (cfun, stmt)
+       && !cfun->can_delete_dead_exceptions)
+      || gimple_call_noreturn_p (stmt))
     return false;
 
   /* If return value is used the call is not dead.  */
-- 
2.47.1

Reply via email to