https://gcc.gnu.org/g:64163657ba7e70347087a63bb2b32d83b52ea7d9

commit r15-3955-g64163657ba7e70347087a63bb2b32d83b52ea7d9
Author: Richard Biener <rguent...@suse.de>
Date:   Thu Sep 26 15:41:59 2024 +0200

    tree-optimization/116850 - corrupt post-dom info
    
    Path isolation computes post-dominators on demand but can end up
    splitting blocks after that, wrecking it.  We can delay splitting
    of blocks until we no longer need the post-dom info which is what
    the following patch does to solve the issue.
    
            PR tree-optimization/116850
            * gimple-ssa-isolate-paths.cc (bb_split_points): New global.
            (insert_trap): Delay BB splitting if post-doms are computed.
            (find_explicit_erroneous_behavior): Process delayed BB
            splitting after releasing post dominators.
            (gimple_ssa_isolate_erroneous_paths): Do not free post-dom
            info here.
    
            * gcc.dg/pr116850.c: New testcase.

Diff:
---
 gcc/gimple-ssa-isolate-paths.cc | 23 ++++++++++++++++++++---
 gcc/testsuite/gcc.dg/pr116850.c | 12 ++++++++++++
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/gcc/gimple-ssa-isolate-paths.cc b/gcc/gimple-ssa-isolate-paths.cc
index fae18db0c1d1..55a516987dbe 100644
--- a/gcc/gimple-ssa-isolate-paths.cc
+++ b/gcc/gimple-ssa-isolate-paths.cc
@@ -62,6 +62,8 @@ check_loadstore (gimple *stmt, tree op, tree, void *data)
   return false;
 }
 
+static vec<gimple *> *bb_split_points;
+
 /* Insert a trap after SI and split the block after the trap.  */
 
 static void
@@ -104,14 +106,20 @@ insert_trap (gimple_stmt_iterator *si_p, tree op)
       gsi_insert_after (si_p, seq, GSI_NEW_STMT);
       if (stmt_ends_bb_p (stmt))
        {
-         split_block (gimple_bb (stmt), stmt);
+         if (dom_info_available_p (CDI_POST_DOMINATORS))
+           bb_split_points->safe_push (stmt);
+         else
+           split_block (gimple_bb (stmt), stmt);
          return;
        }
     }
   else
     gsi_insert_before (si_p, seq, GSI_NEW_STMT);
 
-  split_block (gimple_bb (new_stmt), new_stmt);
+  if (dom_info_available_p (CDI_POST_DOMINATORS))
+    bb_split_points->safe_push (new_stmt);
+  else
+    split_block (gimple_bb (new_stmt), new_stmt);
   *si_p = gsi_for_stmt (stmt);
 }
 
@@ -842,6 +850,8 @@ static void
 find_explicit_erroneous_behavior (void)
 {
   basic_block bb;
+  auto_vec<gimple *> local_bb_split_points;
+  bb_split_points = &local_bb_split_points;
 
   FOR_EACH_BB_FN (bb, cfun)
     {
@@ -883,6 +893,14 @@ find_explicit_erroneous_behavior (void)
            warn_return_addr_local (bb, return_stmt);
        }
     }
+
+  free_dominance_info (CDI_POST_DOMINATORS);
+
+  /* Perform delayed splitting of blocks.  */
+  for (gimple *stmt : local_bb_split_points)
+    split_block (gimple_bb (stmt), stmt);
+
+  bb_split_points = NULL;
 }
 
 /* Search the function for statements which, if executed, would cause
@@ -939,7 +957,6 @@ gimple_ssa_isolate_erroneous_paths (void)
   /* We scramble the CFG and loop structures a bit, clean up
      appropriately.  We really should incrementally update the
      loop structures, in theory it shouldn't be that hard.  */
-  free_dominance_info (CDI_POST_DOMINATORS);
   if (cfg_altered)
     {
       free_dominance_info (CDI_DOMINATORS);
diff --git a/gcc/testsuite/gcc.dg/pr116850.c b/gcc/testsuite/gcc.dg/pr116850.c
new file mode 100644
index 000000000000..7ab5da1848bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr116850.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -w" } */
+
+int a, b;
+int *c()
+{
+  int d, *e = 0, *f = &d, *g = &a;
+  if (b)
+    g = 0;
+  *e = *g;
+  return f;
+}

Reply via email to