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