https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114052

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |needs-bisection

--- Comment #13 from Richard Biener <rguenth at gcc dot gnu.org> ---
On trunk the testcase now works - because of the cunroll side-effect change we
go from

size: 6-1, last_iteration: 6-1
  Loop size: 6
  Estimated size after unrolling: 6
t2.c:1:5: optimized: loop with 1 iterations completely unrolled (header
execution count 10233758)

to

size: 6-1, last_iteration: 6-1
  Loop size: 6
  Estimated size after unrolling: 10-2
Not unrolling loop 1: size would grow.

and we only allow unrolling if the size doesn't grow because there's a call
in the body.  We'd need a new testcase there.


For the issue at hand (not trying to handle other cases we don't have a
testcase for), copying parts of the
tree-ssa-loop-im.cc:fill_always_executed_in_1
handling works (irreducible inner loop and exit not copied).

diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
index b71eb67fbc7..0615fb307d9 100644
--- a/gcc/tree-ssa-loop-niter.cc
+++ b/gcc/tree-ssa-loop-niter.cc
@@ -4378,11 +4378,28 @@ infer_loop_bounds_from_undefined (class loop *loop,
basic_block *bbs)
   gimple_stmt_iterator bsi;
   basic_block bb;
   bool reliable;
+  class loop *inn_loop = loop;

   for (i = 0; i < loop->num_nodes; i++)
     {
       bb = bbs[i];

+      if (!flow_bb_inside_loop_p (inn_loop, bb))
+       {
+         /* When we are leaving a possibly infinite inner loop
+            we have to stop processing.  */
+         if (!finite_loop_p (inn_loop))
+           break;
+         /* If the loop was finite we can continue with processing
+            the loop we exited to.  */
+         inn_loop = bb->loop_father;
+       }
+
+      if (bb->loop_father->header == bb)
+       /* Record that we enter into a subloop since it might not
+          be finite.  */
+       inn_loop = bb->loop_father;
+
       /* If BB is not executed in each iteration of the loop, we cannot
         use the operations in it to infer reliable upper bound on the
         # of iterations of the loop.  However, we can use it as a guess. 
@@ -4812,7 +4829,7 @@ estimate_numbers_of_iterations (class loop *loop)
      diagnose those loops with -Waggressive-loop-optimizations.  */
   number_of_latch_executions (loop);

-  basic_block *body = get_loop_body (loop);
+  basic_block *body = get_loop_body_in_dom_order (loop);
   auto_vec<edge> exits = get_loop_exit_edges (loop, body);
   likely_exit = single_likely_exit (loop, exits);
   FOR_EACH_VEC_ELT (exits, i, ex)

Reply via email to