On Thu, 26 Sep 2024, Richard Biener wrote:

> When path isolation performs CFG manipulations (block splitting) it
> fails to update post-dominators it computes on-demand.  That both
> runs into dominance verification issues when we compute post-dominators
> again and possibly accessing missing or broken post-dominance data
> when checking is disabled.  The following attempts to get rid of
> post-dominator use by approximating always-executed with dominating
> function exit instead of post-dominating function entry.  For this to
> work we have to add fake exit edges.
> 
> Bootstrapped and tested on x86_64-unknown-linux-gnu.
> 
> I'll push this later if nobody has comments.

On a second thought using dominators isn't an equivalent thing.  The
following avoids the issue by delaying splitting of blocks (instead
of implementing post-dominator update for split_block).

Bootstrap & regtest in progress on x86_64-unknown-linux-gnu.

Richard.

>From d1d900b32bfbb146b010dcdc7cc3fdf442fb12d1 Mon Sep 17 00:00:00 2001
From: Richard Biener <rguent...@suse.de>
Date: Thu, 26 Sep 2024 15:41:59 +0200
Subject: [PATCH] tree-optimization/116850 - corrupt post-dom info
To: gcc-patches@gcc.gnu.org

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.
---
 gcc/gimple-ssa-isolate-paths.cc | 23 ++++++++++++++++++++---
 gcc/testsuite/gcc.dg/pr116850.c | 12 ++++++++++++
 2 files changed, 32 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr116850.c

diff --git a/gcc/gimple-ssa-isolate-paths.cc b/gcc/gimple-ssa-isolate-paths.cc
index fae18db0c1d..55a516987db 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 00000000000..7ab5da1848b
--- /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;
+}
-- 
2.43.0

Reply via email to