On Mon, 10 Nov 2025, Victor Do Nascimento wrote:
> 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))
I think the checks on assumptions this last one should be in a
if (! chrec_contains_undetermined (info->number_of_iterations))
section. When the IV is counted and we have to assume 'false' we do
not want to vectorize this - I don't think we want to fall back to
treating the loop as uncounted in this case. So, can you
refactor this to simply early exit from the function for
chrec_contains_undetermined (info->number_of_iterations), eliding
the following checks that only make sense for counted loops?
It might be helpful to dump that the loop is considered uncounted
in this case.
> 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)
LOOP_VINFO_NITERS (L) == chrec_dont_know is cheaper.
Otherwise looks OK to me, but nothing to push early.
Thanks,
Richard.
> #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
>
--
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)