]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/116850 - corrupt post-dom info
authorRichard Biener <rguenther@suse.de>
Thu, 26 Sep 2024 13:41:59 +0000 (15:41 +0200)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 4 Apr 2025 10:10:24 +0000 (12:10 +0200)
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.

(cherry picked from commit 64163657ba7e70347087a63bb2b32d83b52ea7d9)

gcc/gimple-ssa-isolate-paths.cc
gcc/testsuite/gcc.dg/pr116850.c [new file with mode: 0644]

index cc0ed9760a0388fea8f6af732a1d414deab8fa34..7613f83da6aa28fca0af02c9076ffe919874703d 100644 (file)
@@ -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);
 }
 
@@ -840,6 +848,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)
     {
@@ -881,6 +891,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
@@ -937,7 +955,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 (file)
index 0000000..7ab5da1
--- /dev/null
@@ -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;
+}