On Mon, Feb 2, 2026 at 10:08 AM Andrew Pinski
<[email protected]> wrote:
>
> 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.
>
> Bootstrapped and tested on x86_64-linux-gnu.

Hmm, I think you possibly want to check gimple_call_ctrl_altering_p instead?

Richard.

>         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]>
> ---
>  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(-)
>  create mode 100644 gcc/testsuite/gcc.dg/torture/pr121103-1.c
>
> diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
> index ec6831a20a0..7ae5425376f 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 are marked as noreturn. */
> +  if (gimple_call_flags (stmt) & ECF_NORETURN)
> +    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 00000000000..22f76c528df
> --- /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 13266310ebe..10ae5d6e2ac 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_flags (stmt) & ECF_NORETURN))
>      {
>        tree fndecl = gimple_call_fndecl (stmt);
>        switch (DECL_FUNCTION_CODE (fndecl))
> --
> 2.43.0
>

Reply via email to