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.

Thanks,
Richard.

        PR tree-optimization/116850
        * gimple-ssa-isolate-paths.cc (warn_return_addr_local): Use
        dominance and not post-dominance to compute maybe.
        (gimple_ssa_isolate_erroneous_paths): Add/remove fake exit edges.

        * gcc.dg/pr116850.c: New testcase.
---
 gcc/gimple-ssa-isolate-paths.cc | 18 ++++++++++--------
 gcc/testsuite/gcc.dg/pr116850.c | 11 +++++++++++
 2 files changed, 21 insertions(+), 8 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..c755e68cd57 100644
--- a/gcc/gimple-ssa-isolate-paths.cc
+++ b/gcc/gimple-ssa-isolate-paths.cc
@@ -802,16 +802,17 @@ warn_return_addr_local (basic_block bb, greturn 
*return_stmt)
   if (!is_addr_local (return_stmt, val, &locmap, &visited_phis))
     return;
 
-  /* We only need it for this particular case.  */
-  calculate_dominance_info (CDI_POST_DOMINATORS);
-
   const args_loc_t *argsloc = locmap.get (return_stmt);
   gcc_assert (argsloc);
 
-  bool maybe = argsloc->nargs > argsloc->locvec.length ();
-  if (!maybe)
-    maybe = !dominated_by_p (CDI_POST_DOMINATORS,
-                            single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)), bb);
+  /* We have fake edges to exit from inifinite loops and noreturn calls so
+     we can use dominance from a single exit edge to approximate whether BB
+     is always executed.  */
+  bool maybe = (argsloc->nargs > argsloc->locvec.length ()
+               || !single_pred_p (EXIT_BLOCK_PTR_FOR_FN (cfun))
+               || !dominated_by_p (CDI_DOMINATORS,
+                                   single_pred (EXIT_BLOCK_PTR_FOR_FN (cfun)),
+                                   bb));
 
   diag_returned_locals (maybe, locmap);
 
@@ -913,6 +914,7 @@ static unsigned int
 gimple_ssa_isolate_erroneous_paths (void)
 {
   initialize_original_copy_tables ();
+  connect_infinite_loops_to_exit ();
 
   /* Search all the blocks for edges which, if traversed, will
      result in undefined behavior.  */
@@ -939,7 +941,7 @@ 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);
+  remove_fake_exit_edges ();
   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..07c8c42dd65
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr116850.c
@@ -0,0 +1,11 @@
+/* { 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