On Wed, Aug 12, 2026 at 11:59 PM Andrea Pinski
<[email protected]> wrote:
>
> r17-3204-ge02ce3b8c4574c added a no_delete to simple_dce_from_worklist.
> With the no_delete option, for calls where the lhs would be removed,
> simple_dce_from_worklist would insert an assignment after the call.
> But with exceptions the call is required to be last stmt in the basic block.
> Note inserting before the call would not work either because of requirements
> of returns twice functions need to be the first stmt of the basic block (
> see gimple_verify_flow_info).
> So the fix is instead just not removing the lhs for no_delete case.
>
> Pushed as obvious after a bootstrap/test on x86_64-linux-gnu.
>
>         PR tree-optimization/126815
>
> gcc/ChangeLog:
>
>         * tree-ssa-dce.cc (simple_dce_from_worklist): Just don't
>         remove the lhs for no_delete case rather than adding a
>         new stmt.
>
> gcc/testsuite/ChangeLog:
>
>         * g++.dg/torture/pr126815-1.C: New test.
>
> Signed-off-by: Andrea Pinski <[email protected]>
> ---
>  gcc/testsuite/g++.dg/torture/pr126815-1.C | 20 ++++++++++++++++++++
>  gcc/tree-ssa-dce.cc                       | 13 +++----------
>  2 files changed, 23 insertions(+), 10 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/torture/pr126815-1.C
>
> diff --git a/gcc/testsuite/g++.dg/torture/pr126815-1.C 
> b/gcc/testsuite/g++.dg/torture/pr126815-1.C
> new file mode 100644
> index 00000000000..227fdb4505f
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/torture/pr126815-1.C
> @@ -0,0 +1,20 @@
> +// PR tree-optimization/126815
> +// { dg-do compile }
> +
> +
> +struct Guard { ~Guard (); };      // EH cleanup: makes f() end its basic 
> block
> +int f (int);
> +void sink (int);
> +
> +void h (int a, int b, int c)
> +{
> +  Guard g;
> +  int t;
> +  if (c)
> +    t = f (a);                    // throwing call feeds the PHI
> +  else
> +    t = b;                        // non-constant: prevents jump threading
> +  if (t == 42)                    // t's only use
> +    __builtin_unreachable ();
> +  sink (a);
> +}
> diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc
> index bf818ad2c91..9fdd102442a 100644
> --- a/gcc/tree-ssa-dce.cc
> +++ b/gcc/tree-ssa-dce.cc
> @@ -2224,19 +2224,12 @@ simple_dce_from_worklist (bitmap worklist, bitmap 
> need_eh_cleanup,
>        if (gimple_has_side_effects (t))
>         {
>           gcall *call = dyn_cast <gcall *> (t);
> -         if (call)
> +         // For no delete don't remove the lhs.
> +         if (call && no_delete)

I just noticed after pushing this patch I messed up the condition. It
should have been call && !no_delete.
Whoops.
Will update and push a patch to fix that. Yes I didn't run into a
bootstrap or testcase failure with it so maybe there was no testcase
testing it though.

>             {
>               gimple_call_set_lhs (call, NULL_TREE);
>               update_stmt (call);
> -             if (no_delete)
> -               {
> -                 tree zero = build_zero_cst (TREE_TYPE (def));
> -                 gassign *new_stmt = gimple_build_assign (def, zero);
> -                 gimple_stmt_iterator gsi = gsi_for_stmt (t);
> -                 gsi_insert_after (&gsi, new_stmt, GSI_SAME_STMT);
> -               }
> -             else
> -               release_ssa_name (def);
> +             release_ssa_name (def);
>             }
>           continue;
>         }
> --
> 2.43.0
>

Reply via email to