In its current implementation, the loop vectorizer requires the main
exit be the counting IV exit. With uncounted loops we no longer need
to have any counting IV exits.  Furthermore, it is possible to have
reached this stage with malformed loops with no exits at all.

Consequently, we need an approach to handle malformed loops and some
logic to follow when choosing the main exit, when counting IV is no
longer a valid criterion.

For malformed loops, it is sufficient to return NULL, so that we can
reject such loops upon the function return.

In the case of multiple exits and no counting IV exit, we choose the
last one in the loop.  This is done so that we continue to have an
empty effective latch.

gcc/ChangeLog:

        * tree-vect-loop.cc (vec_init_loop_exit_info): Handle
        multiple-exit uncounted loops.
        * tree-vect-loop.cc (vec_init_loop_exit_info): Handle
        ill-formed loops with no exits.
        (vect_analyze_loop_form): Fix `failure_at' message.
---
 gcc/tree-vect-loop.cc | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 8d5fb64ca9c..dfb0960e7d1 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -657,6 +657,8 @@ vec_init_loop_exit_info (class loop *loop)
   /* Before we begin we must first determine which exit is the main one and
      which are auxilary exits.  */
   auto_vec<edge> exits = get_loop_exit_edges (loop);
+  if (exits.length () == 0)
+    return NULL;
   if (exits.length () == 1)
     return exits[0];
 
@@ -688,6 +690,17 @@ vec_init_loop_exit_info (class loop *loop)
        }
     }
 
+  /* If no exit is analyzable by scalar evolution, we return the last exit
+     under the assummption we are dealing with an uncounted loop.  */
+  if (!candidate)
+    for (edge exit : exits)
+      if (single_pred_p (loop->latch)
+         && exit->src == single_pred (loop->latch))
+       {
+         candidate = exit;
+         break;
+       }
+
   return candidate;
 }
 
@@ -1438,8 +1451,7 @@ vect_analyze_loop_form (class loop *loop, gimple 
*loop_vectorized_call,
   if (!exit_e)
     return opt_result::failure_at (vect_location,
                                   "not vectorized:"
-                                  " could not determine main exit from"
-                                  " loop with multiple exits.\n");
+                                  " Infinite loop detected.\n");
   if (loop_vectorized_call)
     {
       tree arg = gimple_call_arg (loop_vectorized_call, 1);
-- 
2.43.0

Reply via email to