At present we reject uncounted loops outright when doing initial loop
analysis in `vect_analyze_loop_form'.

We have the following gating condition that causes rejection of a
given loop:

 if (integer_zerop (info->assumptions)
      || !info->number_of_iterations
      || chrec_contains_undetermined (info->number_of_iterations))

We can do away with this check altogether, but not without problems,
allowing many malformed loops through which ought to be rejected as
early as possible.

We observe that a common thread running through these malformed loops
is the absence of any scalar evolution between iterations.

We have therefore adjusted the analysis replacing the checks on
`niters' for a test for the presence of scalar evolution in the loop,
which can be detected via the presence of phi nodes in the loop.

- Detecting uncounted loops going forward:

Given that scalar evolution analysis of uncounted loops sets
`loop_vec_info->num_iters' to `SCEV_NOT_KNOWN', we use this as the
criterion for probing whether a loop is uncounted or not.
Consequently, we introduce a new access function on `loop_vec_info' to
conveniently test whether a loop in question is uncounted or not, in
the form of `LOOP_VINFO_NITERS_UNCOUNTED_P(L)'.

gcc/ChangeLog:

        * tree-vect-loop.cc (vect_analyze_loop_form): Relax niters
        condition.
        * tree-vectorizer.h (LOOP_VINFO_NITERS_UNCOUNTED_P): New.
---
 gcc/tree-vect-loop.cc | 21 ++++++++++++++-------
 gcc/tree-vectorizer.h |  2 ++
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 576a69c82d2..b317386dc18 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -1470,6 +1470,20 @@ vect_analyze_loop_form (class loop *loop, gimple 
*loop_vectorized_call,
                                       "not vectorized:"
                                       " unsupported control flow in loop.\n");
       }
+
+  /* Check if we have any control flow that doesn't leave the loop.  */
+  bool has_phi = false;
+  for (unsigned i = 0; i < loop->num_nodes; i++)
+    if (!gimple_seq_empty_p (phi_nodes (bbs[i])))
+      {
+       has_phi = true;
+       break;
+      }
+  if (!has_phi)
+    return opt_result::failure_at (vect_location,
+                                  "not vectorized:"
+                                  " no scalar evolution detected in loop.\n");
+
   free (bbs);
 
   /* Different restrictions apply when we are considering an inner-most loop,
@@ -1594,13 +1608,6 @@ vect_analyze_loop_form (class loop *loop, gimple 
*loop_vectorized_call,
        std::swap (info->conds[0], info->conds[i]);
     }
 
-  if (integer_zerop (info->assumptions)
-      || !info->number_of_iterations
-      || chrec_contains_undetermined (info->number_of_iterations))
-    return opt_result::failure_at
-      (info->conds[0],
-       "not vectorized: number of iterations cannot be computed.\n");
-
   if (integer_zerop (info->number_of_iterations))
     return opt_result::failure_at
       (info->conds[0],
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index b7f3297a16b..bbc2e0df01d 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -1259,6 +1259,8 @@ public:
 /* Since LOOP_VINFO_NITERS and LOOP_VINFO_NITERSM1 can change after
    prologue peeling retain total unchanged scalar loop iterations for
    cost model.  */
+#define LOOP_VINFO_NITERS_UNCOUNTED_P(L)   (TREE_CODE (LOOP_VINFO_NITERS (L)) \
+                                           == SCEV_NOT_KNOWN)
 #define LOOP_VINFO_NITERS_UNCHANGED(L)     (L)->num_iters_unchanged
 #define LOOP_VINFO_NITERS_ASSUMPTIONS(L)   (L)->num_iters_assumptions
 #define LOOP_VINFO_COST_MODEL_THRESHOLD(L) (L)->th
-- 
2.43.0

Reply via email to