https://gcc.gnu.org/g:36a5d12cca2bc3b6d06432f10206188c1799479e

commit r16-7598-g36a5d12cca2bc3b6d06432f10206188c1799479e
Author: Andrew Pinski <[email protected]>
Date:   Sun Feb 1 21:08:54 2026 -0800

    fold/dse: Don't simplify/remove noreturn functions [PR121103]
    
    This fixes 2 related bugs. The user marks memmove as noreturn
    so when we simplify the memmove to a memory load/store there
    is no longer a statement that can alter the CFG and things go
    down hill.
    The same is true for removing the call in DSE.
    So the fix is not to simplify/take into account the call from
    gimple-fold and DSE.
    
    changes since v1:
     * v2: Use gimple_call_ctrl_altering_p instead of flags.
    
    Bootstrapped and tested on x86_64-linux-gnu.
    
            PR tree-optimization/121103
    
    gcc/ChangeLog:
    
            * gimple-fold.cc (gimple_fold_call): Don't simplify
            noreturn functions.
            * tree-ssa-dse.cc (dse_optimize_stmt): Don't handle
            calls to noreturn functions.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/torture/pr121103-1.c: New test.
    
    Signed-off-by: Andrew Pinski <[email protected]>

Diff:
---
 gcc/gimple-fold.cc                        |  4 ++++
 gcc/testsuite/gcc.dg/torture/pr121103-1.c | 40 +++++++++++++++++++++++++++++++
 gcc/tree-ssa-dse.cc                       |  3 ++-
 3 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index ec6831a20a05..bc8540a8c5c3 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -6068,6 +6068,10 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool 
inplace)
   if (inplace)
     return changed;
 
+  /* Don't constant fold functions which can change the control. */
+  if (gimple_call_ctrl_altering_p (stmt))
+    return changed;
+
   /* Check for builtins that CCP can handle using information not
      available in the generic fold routines.  */
   if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
diff --git a/gcc/testsuite/gcc.dg/torture/pr121103-1.c 
b/gcc/testsuite/gcc.dg/torture/pr121103-1.c
new file mode 100644
index 000000000000..22f76c528df7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr121103-1.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* PR tree-optimization/121103 */
+
+extern void *memmove(void *, const void *, __SIZE_TYPE__) 
__attribute__((noreturn));
+
+struct A {
+  const char *s;
+  int n;
+};
+
+void f(void *);
+
+struct B {
+  char d[5];
+  int n;
+};
+
+__attribute__((always_inline)) inline void g(struct B *p, struct A a) {
+  int i = a.n;
+  if (i <= 5)
+    p->n = i;
+  else {
+    p->n = -1;
+    f(p);
+  }
+
+  if (p->n >= 0)
+    memmove(p->d, a.s, a.n); /* { dg-bogus "\\\[-Warray-bounds" } */
+}
+
+void h(void) {
+  char c[8] = "";
+
+  struct A a;
+  a.s = c;
+  a.n = 8;
+
+  struct B b;
+  g(&b, a);
+}
diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc
index 13266310ebea..cc381b4cd7b0 100644
--- a/gcc/tree-ssa-dse.cc
+++ b/gcc/tree-ssa-dse.cc
@@ -1501,7 +1501,8 @@ dse_optimize_stmt (function *fun, gimple_stmt_iterator 
*gsi, sbitmap live_bytes)
 
   /* We know we have virtual definitions.  We can handle assignments and
      some builtin calls.  */
-  if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
+  if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
+      && !gimple_call_ctrl_altering_p (stmt))
     {
       tree fndecl = gimple_call_fndecl (stmt);
       switch (DECL_FUNCTION_CODE (fndecl))

Reply via email to