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;