https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106408
--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- An incomplete solution on the GIMPLE level is the following. It's incomplete because there's a hole for irreducible regions which we do not represent explicitely (nor their sub-irreducible regions). rev_post_order_and_mark_dfs_back_seme has a simplified loop discovery code that would properly compute this. Just considering all blocks in irreducible regions as BB_MAY_NORETURN will inhibit all in-region PRE which is probably undesirable. OTOH the code below will unnecessarily pessimize "well written" loops while leaving the bug open for the bad ones. diff --git a/gcc/tree-ssa-pre.cc b/gcc/tree-ssa-pre.cc index e029bd36da3..76dbef4cff3 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,12 @@ compute_avail (function *fun) BB_MAY_NOTRETURN (block) = 0; + /* 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; + /* Now compute value numbers and populate value sets with all the expressions computed in BLOCK. */ bool set_bb_may_notreturn = false;