On Fri, Nov 7, 2025 at 1:32 AM Andrew Pinski
<[email protected]> wrote:
>
> When optimize_unreachable was moved from fab to forwprop, I missed that due to
> the integrated copy prop, we might end up with an already true branch leading
> to a __builtin_unreachable block. optimize_unreachable would switch around
> the if and things go down hill from there since the other edge was already
> marked as non-executable, forwprop didn't process those blocks and didn't
> do copy prop into that block and the original assignment statement was 
> removed.
>
> This fixes the problem by having optimize_unreachable not touch the if
> statement was already changed to true/false.
>
> Note I placed the testcase in gcc.c-torture/compile as gcc.dg/torture
> is NOT currently testing -Og (see PR 122450 for that).
>
> Changes since v1:
>  * v2: Add gimple testcase.
>
> Bootstrapped and tested on x86_64-linux-gnu.

OK.

>         PR tree-optimization/122588
>
> gcc/ChangeLog:
>
>         * tree-ssa-forwprop.cc (optimize_unreachable): Don't touch
>         if the condition was already true or false.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.c-torture/compile/pr122588-1.c: New test.
>         * gcc.dg/tree-ssa/pr122588-1.c: New test.
>
> Signed-off-by: Andrew Pinski <[email protected]>
> ---
>  .../gcc.c-torture/compile/pr122588-1.c        | 25 ++++++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/pr122588-1.c    | 30 +++++++++++++++++++
>  gcc/tree-ssa-forwprop.cc                      |  7 ++++-
>  3 files changed, 61 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr122588-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr122588-1.c
>
> diff --git a/gcc/testsuite/gcc.c-torture/compile/pr122588-1.c 
> b/gcc/testsuite/gcc.c-torture/compile/pr122588-1.c
> new file mode 100644
> index 00000000000..43ec621512c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.c-torture/compile/pr122588-1.c
> @@ -0,0 +1,25 @@
> +/* Disable warnings about __sync_nand_and_fetch. */
> +/* { dg-options "-w" } */
> +/* PR tree-optimization/122588 */
> +
> +int i;
> +char c;
> +
> +static inline __attribute__((__always_inline__))
> +void foo0 (int a)
> +{
> +l5:
> +  __sync_nand_and_fetch (&i, 0);
> +  int x = __builtin_memcmp_eq (&a, 0, 4);
> +  if (__builtin_iseqsig (x, 0.))
> +    goto l5;
> +  if (a)
> +    __builtin_unreachable ();
> +  c = a;
> +}
> +
> +int
> +main ()
> +{
> +  foo0 (1);
> +}
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr122588-1.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/pr122588-1.c
> new file mode 100644
> index 00000000000..2c214c90576
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr122588-1.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O1 -fgimple" } */
> +/* PR tree-optimization/122588 */
> +
> +/* The removal of unreachable blocks should not
> +   change blocks which have already become true/false.
> +   The function below was is an example of that. And
> +   forwprop does not go into non-executable blocks
> +   so the statement `t = _1;` was still holding the
> +   old reference.  */
> +
> +int t;
> +
> +__GIMPLE(ssa,startwith("forwprop4")) void g(void)
> +{
> +  int _1;
> +  __BB(2):
> +  _1 = 1;
> +  if (_1 != 0)
> +    goto __BB3;
> +  else
> +    goto __BB4;
> +
> +  __BB(3):
> +  __builtin_unreachable ();
> +
> +  __BB(4):
> +  t = _1;
> +  return;
> +}
> diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
> index ae7f0e770ba..9f8d4ad3b44 100644
> --- a/gcc/tree-ssa-forwprop.cc
> +++ b/gcc/tree-ssa-forwprop.cc
> @@ -5080,7 +5080,12 @@ optimize_unreachable (basic_block bb)
>        stmt = gsi_stmt (gsi);
>        if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
>         {
> -         if (e->flags & EDGE_TRUE_VALUE)
> +         /* If the condition is already true/false
> +            ignore it. This can happen during copy prop of forwprop. */
> +         if (gimple_cond_true_p (cond_stmt)
> +             || gimple_cond_false_p (cond_stmt))
> +           continue;
> +         else if (e->flags & EDGE_TRUE_VALUE)
>             gimple_cond_make_false (cond_stmt);
>           else if (e->flags & EDGE_FALSE_VALUE)
>             gimple_cond_make_true (cond_stmt);
> --
> 2.43.0
>

Reply via email to