https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106408
--- Comment #3 from rguenther at suse dot de <rguenther at suse dot de> --- On Fri, 22 Jul 2022, hubicka at ucw dot cz wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106408 > > --- Comment #2 from Jan Hubicka <hubicka at ucw dot cz> --- > > + /* If block is a loop that is possibly infinite we should not > > + hoist across it. */ > > + if (block->loop_father->header == block > > + && !finite_loop_p (block->loop_father)) > > + BB_MAY_NOTRETURN (block) = 1; > > + > Don't you just need to handle also BBs that have backedge out that is > not a latch of loop? I would need to handle all blocks with an incoming backedge, and for non-irreducible regions can use finite_loop_p, yes. Not sure what you mean with backedge out. So the following would handle loops and irreducible regions correctly I think. diff --git a/gcc/tree-ssa-pre.cc b/gcc/tree-ssa-pre.cc index e029bd36da3..a2d8b52f872 100644 --- a/gcc/tree-ssa-pre.cc +++ b/gcc/tree-ssa-pre.cc @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-cfgcleanup.h" #include "alias.h" #include "gimple-range.h" +#include "tree-ssa-loop-niter.h" /* Even though this file is called tree-ssa-pre.cc, we actually implement a bit more than just PRE here. All of them piggy-back @@ -3939,6 +3940,16 @@ compute_avail (function *fun) BB_MAY_NOTRETURN (block) = 0; + /* If this block is an entry into a CFG cycle that is possibly infinite + we should not hoist across it. */ + edge_iterator ei; + edge e; + FOR_EACH_EDGE (e, ei, block->preds) + if ((e->flags & EDGE_DFS_BACK) + && (block->loop_father->header != block + || !finite_loop_p (block->loop_father))) + BB_MAY_NOTRETURN (block) = 1; + /* Now compute value numbers and populate value sets with all the expressions computed in BLOCK. */ bool set_bb_may_notreturn = false;