On Tue, Feb 24, 2026 at 6:40 AM Andrew Pinski
<[email protected]> wrote:
>
> After outlinining the bbs for function splitting, we move the clobbers that 
> were in the
> last bb to be after the newly calling function.
> This allows for stack location sharing and more when the non split out part 
> is inlined
> into another function.
>
> This also fixes some of the warnings about dangling-pointers because
> the clobbers are now correctly handled while function splitting.
> The testcases test for the cases where the dangling-pointers pointer
> warnings would show up too.
>
> Note only end of storage clobbers in this case.
>
> Bootstrapped and tested on x86_64-linux-gnu.
>
>         PR tree-optimization/110091
>
> gcc/ChangeLog:
>
>         * ipa-split.cc (split_function): Find the bb
>         which is used for return in the outlined function.
>         Move the clobbers that are at the end of that bb
>         to be after the new call.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/tree-ssa/pr110091-3.c: New test.
>         * gcc.dg/tree-ssa/pr110091-4.c: New test.
>
> Signed-off-by: Andrew Pinski <[email protected]>
> ---
>  gcc/ipa-split.cc                           | 48 ++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/pr110091-3.c | 38 +++++++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/pr110091-4.c | 34 +++++++++++++++
>  3 files changed, 120 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr110091-3.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr110091-4.c
>
> diff --git a/gcc/ipa-split.cc b/gcc/ipa-split.cc
> index 3185830609d..aae4cf9e151 100644
> --- a/gcc/ipa-split.cc
> +++ b/gcc/ipa-split.cc
> @@ -1470,8 +1470,31 @@ split_function (basic_block return_bb, class 
> split_point *split_point,
>        }
>      else
>        break;
> +
> +  /* Find the old return bb, it might contain some clobbers
> +     which we want to copy back after the call.  */
> +  basic_block old_return = nullptr;
> +  if (split_part_return_p)
> +    {
> +      bool one_return_bb = true;
> +      FOR_EACH_EDGE (e, ei, return_bb->preds)
> +       if (bitmap_bit_p (split_point->split_bbs, e->src->index))
> +         {
> +           if (old_return != nullptr)
> +             {
> +               one_return_bb = false;
> +               break;
> +             }
> +           old_return = e->src;
> +         }
> +      if (!one_return_bb)
> +       old_return = nullptr;
> +    }
> +
>    call_bb->count = split_point->count;
>    e = split_block (split_point->entry_bb, last_stmt);
> +  if (old_return == e->src)
> +    old_return = e->dest;
>    remove_edge (e);
>
>    /* Produce the call statement.  */
> @@ -1713,6 +1736,31 @@ split_function (basic_block return_bb, class 
> split_point *split_point,
>           gsi_insert_after (&gsi, ret, GSI_NEW_STMT);
>         }
>      }
> +
> +  /* Move the clobbers from the old return bb to after the call. */
> +  if (old_return)
> +    {
> +      gimple_stmt_iterator ngsi = gsi_last_bb (call_bb);
> +      gsi_next (&ngsi);
> +      for (gimple_stmt_iterator ogsi = gsi_last_bb (old_return);
> +          !gsi_end_p (ogsi); )
> +       {
> +         gimple *stmt = *ogsi;
> +         if (is_gimple_debug (stmt))
> +           {
> +             gsi_prev (&ogsi);
> +             continue;
> +           }
> +         if (!gimple_clobber_p (stmt, CLOBBER_STORAGE_END))
> +           break;
> +         gimple_set_vuse (stmt, gimple_vop (cfun));
> +         gimple_set_vdef (stmt, gimple_vop (cfun));

I believe this will leak an unreleased SSA name.  You might want to use
unlink_stmt_vdef before?

> +         gimple_stmt_iterator nogsi = ogsi;
> +         gsi_prev (&ogsi);
> +         gsi_move_before (&nogsi, &ngsi, GSI_NEW_STMT);
> +         update_stmt (stmt);
> +       }
> +    }
>    free_dominance_info (CDI_DOMINATORS);
>    free_dominance_info (CDI_POST_DOMINATORS);
>    compute_fn_summary (node, true);
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110091-3.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/pr110091-3.c
> new file mode 100644
> index 00000000000..532b138655f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110091-3.c
> @@ -0,0 +1,38 @@
> +/* { dg-do compile } */
> +/* { dg-options "-Wall -O2 -fdump-tree-optimized -fdump-tree-sink1-details" 
> } */
> +/* PR tree-optimization/110091 */
> +/* The clobbers are after the outlined code */
> +
> +struct tEntry
> +{
> +    int value;
> +};
> +int *out;
> +
> +extern int otherfunc(struct tEntry *);
> +extern void anotherfunc(int val);
> +
> +void bar()
> +{
> +    struct tEntry entry1 = { 0 };
> +    struct tEntry entry2 = { 0 };
> +
> +    if (otherfunc(&entry2) != 0)
> +      return;
> +    if (otherfunc(&entry1) != 0)
> +      return;
> +    if (out)
> +     *out = entry2.value; /* { dg-bogus "dangling pointer to" } */
> +    anotherfunc(5);
> +}
> +
> +void foo()
> +{
> +    bar();
> +}
> +
> +/* There should be 2 CLOBBERs, 1 for each: entry1 and entry2 as they have 
> been "sinked".  */
> +/* { dg-final { scan-tree-dump-times "CLOBBER\\\(eos\\\)" 2 "optimized" } } 
> */
> +/* { dg-final { scan-tree-dump "sinking common stores with same value to 
> entry2" "sink1" } } */
> +/* { dg-final { scan-tree-dump "sinking common stores with same value to 
> entry1" "sink1" } } */
> +
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110091-4.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/pr110091-4.c
> new file mode 100644
> index 00000000000..e2ce19b0e83
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110091-4.c
> @@ -0,0 +1,34 @@
> +/* { dg-do compile } */
> +/* { dg-options "-Wall -O2 -fdump-tree-optimized -fdump-tree-sink1-details" 
> } */
> +/* PR tree-optimization/110091 */
> +/* The clobbers are after the outlined code */
> +
> +struct tEntry
> +{
> +    int value;
> +};
> +int *out;
> +
> +extern int otherfunc(struct tEntry *);
> +extern void anotherfunc(int val);
> +
> +void bar()
> +{
> +    struct tEntry entry = { 0 };
> +
> +    if (otherfunc(&entry) != 0)
> +      return;
> +    if (out)
> +     *out = entry.value; /* { dg-bogus "dangling pointer to" } */
> +    anotherfunc(5);
> +}
> +
> +void foo()
> +{
> +    bar();
> +}
> +
> +/* There should be 2 CLOBBERs, 1 for entry as they have been "sinked" and 
> one for the inlined version.  */
> +/* { dg-final { scan-tree-dump-times "CLOBBER\\\(eos\\\)" 2 "optimized" } } 
> */
> +/* { dg-final { scan-tree-dump "sinking common stores with same value to 
> entry" "sink1" } } */
> +
> --
> 2.43.0
>

Reply via email to