https://gcc.gnu.org/g:a9112128eef1c0455340c2aa3b64303072030746

commit r16-7696-ga9112128eef1c0455340c2aa3b64303072030746
Author: Andrew Pinski <[email protected]>
Date:   Sat Feb 21 14:38:12 2026 -0800

    fn-split: Insert new call after clobbers/debug stmt [PR110091]
    
    So for function splitting when we outlined the function, we
    should keep around the clobbers that were at the begining of
    the bb which will be outlined. So change the last stmt
    to where we split the bb for where the function call will be
    to be after the clobbers.
    
    Note we have to ignore the debug stmts here otherwise you would
    get a debug comparison failure.
    
    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): Split after
            the clobbers/debug stmts rather than after the labels.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/tree-ssa/pr110091-1.c: New test.
            * gcc.dg/tree-ssa/pr110091-2.c: New test.
    
    Signed-off-by: Andrew Pinski <[email protected]>

Diff:
---
 gcc/ipa-split.cc                           |  6 +++--
 gcc/testsuite/gcc.dg/tree-ssa/pr110091-1.c | 38 ++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr110091-2.c | 35 +++++++++++++++++++++++++++
 3 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/gcc/ipa-split.cc b/gcc/ipa-split.cc
index fd1860bf50a5..3185830609da 100644
--- a/gcc/ipa-split.cc
+++ b/gcc/ipa-split.cc
@@ -1458,10 +1458,12 @@ split_function (basic_block return_bb, class 
split_point *split_point,
     dump_function_to_file (node->decl, dump_file, dump_flags);
 
   /* Create the basic block we place call into.  It is the entry basic block
-     split after last label.  */
+     split after last label and after the last eos clobber and debug stmt.  */
   call_bb = split_point->entry_bb;
   for (gimple_stmt_iterator gsi = gsi_start_bb (call_bb); !gsi_end_p (gsi);)
-    if (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
+    if (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
+       || gimple_clobber_p (gsi_stmt (gsi), CLOBBER_STORAGE_END)
+       || is_gimple_debug (gsi_stmt (gsi)))
       {
        last_stmt = gsi_stmt (gsi);
        gsi_next (&gsi);
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110091-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr110091-1.c
new file mode 100644
index 000000000000..793a832ec058
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110091-1.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall -O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/110091 */
+/* The clobbers are before 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 entry = { 0 };
+
+    if (otherfunc(&entry) != 0)
+      return;
+    if (otherfunc(&entry1) != 0)
+      return;
+    if (out)
+     *out = entry.value; /* { dg-bogus "dangling pointer to" } */
+  }
+  anotherfunc(5);
+}
+
+void foo()
+{
+    bar();
+}
+
+/* There should be 4 CLOBBERs, 2 for entry1 and 2 for entry.  */
+/* { dg-final { scan-tree-dump-times "CLOBBER\\\(eos\\\)" 4 "optimized" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110091-2.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr110091-2.c
new file mode 100644
index 000000000000..d85121103962
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110091-2.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall -O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/110091 */
+/* The clobbers are before 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 4 CLOBBERs, 4 for entry; inlined doubles the clobber; 
return path adds clobber.   */
+/* { dg-final { scan-tree-dump-times "CLOBBER\\\(eos\\\)" 4 "optimized" } } */
+

Reply via email to