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;

Reply via email to