On Wed, Feb 25, 2026 at 1:48 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. > > Changes since v1: > * v2: Add comments and add a call to unlink_stmt_vdef/release_ssa_name. > > Bootstrapped and tested on x86_64-linux-gnu.
OK. Thanks, Richard. > 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 | 53 ++++++++++++++++++++++ > gcc/testsuite/gcc.dg/tree-ssa/pr110091-3.c | 38 ++++++++++++++++ > gcc/testsuite/gcc.dg/tree-ssa/pr110091-4.c | 34 ++++++++++++++ > 3 files changed, 125 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..b31235c99cf 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,36 @@ 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; > + /* Change the vdef/vuse of the clobber to be renamed. */ > + unlink_stmt_vdef (stmt); > + release_ssa_name (gimple_vdef (stmt)); > + gimple_set_vuse (stmt, gimple_vop (cfun)); > + gimple_set_vdef (stmt, gimple_vop (cfun)); > + gimple_stmt_iterator nogsi = ogsi; > + > + /* Move to the previous stmt before the move happens. */ > + 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 >
