On Mon, 10 Nov 2025, Victor Do Nascimento wrote:

> For uncounted loops, given how no information can be derived from the
> max number of iterations, we wish to make no distinction between the
> "main" exit and any additional exits.
> 
> That is, an epilogue is required across all exits to establish when
> the exit condition was met within the final vectorized loop iteration.
> 
> This can be accomplished via a two-fold approach:
> 
>      1. The need for all exits to go to the epilogue is shared with
>      counted loops with early-break exits after the IV-counting exit.
>      Such counted loops have the `LOOP_VINFO_EARLY_BREAKS_VECT_PEELED'
>      flag set.  By modifying the flag's definition to encompass
>      uncounted loops, we can make considerable use of the code written
>      for this category of counted loops.
> 
>      2. Currently, when populating the `loop_vinfo' struct for a given
>      loop, there is an assumption that the first exit condition in the
>      `vect_loop_form_info' struct is the IV condition and any
>      subsequent conditions are early break conditions.  This
>      assumption breaks down for uncounted loops where _all_ exits
>      should be treated as being "early break" exits.
> 
>      This is fixed by populating `LOOP_VINFO_LOOP_IV_COND (loop_vinfo)'
>      conditionally on the false evaluation of the
>      `LOOP_VINFO_NITERS_UNCOUNTED_P (loop_vinfo)' predicate, such that
>      if we do have an uncounted loop we leave this field unpopulated,
>      storing all conditions in `LOOP_VINFO_LOOP_CONDS (loop_vinfo)'.
>      This approach has a further benefit in that, give how
>      `LOOP_VINFO_EARLY_BREAKS' is defined by a non-empty list of early
>      break exit conditions (`LOOP_VINFO_LOOP_CONDS (loop_vinfo)'),
>      having LOOP_VINFO_LOOP_CONDS populated even for single-exit
>      uncounted loops means that `LOOP_VINFO_EARLY_BREAKS' evaluates to
>      true for all uncounted loops, irrespective of the number of exits
>      it has.
> 
> gcc/ChangeLog:
> 
>       * tree-vectorizer.h (LOOP_VINFO_EARLY_BREAKS_VECT_PEELED): OR
>       its current definition with `LOOP_VINFO_NITERS_UNCOUNTED_P(L)'
>       * tree-vect-loop.cc (vect_create_loop_vinfo): Don't populate
>       `LOOP_VINFO_LOOP_IV_COND' for uncounted loops.
> ---
>  gcc/tree-vect-loop.cc | 9 ++++++---
>  gcc/tree-vectorizer.h | 3 ++-
>  2 files changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
> index b317386dc18..8d5fb64ca9c 100644
> --- a/gcc/tree-vect-loop.cc
> +++ b/gcc/tree-vect-loop.cc
> @@ -1668,9 +1668,12 @@ vect_create_loop_vinfo (class loop *loop, 
> vec_info_shared *shared,
>        STMT_VINFO_DEF_TYPE (loop_cond_info) = vect_condition_def;
>      }
>  
> -  for (unsigned i = 1; i < info->conds.length (); i ++)
> -    LOOP_VINFO_LOOP_CONDS (loop_vinfo).safe_push (info->conds[i]);
> -  LOOP_VINFO_LOOP_IV_COND (loop_vinfo) = info->conds[0];
> +  unsigned cond_id = 0;
> +  if (!LOOP_VINFO_NITERS_UNCOUNTED_P (loop_vinfo))
> +      LOOP_VINFO_LOOP_IV_COND (loop_vinfo) = info->conds[cond_id++];
> +
> +  for (; cond_id < info->conds.length (); cond_id ++)
> +    LOOP_VINFO_LOOP_CONDS (loop_vinfo).safe_push (info->conds[cond_id]);
>  
>    LOOP_VINFO_IV_EXIT (loop_vinfo) = info->loop_exit;
>  

This looks good in principle.  I do wonder about population of
LOOP_VINFO_IV_EXIT - if you re-order the test below do we have
unguarded (by !LOOP_VINFO_NITERS_UNCOUNTED_P) uses of it?

I guess eventually renaming it to LOOP_VINFO_MAIN_EXIT would be
another option.

Consider this a cosmetic comment, the patch is fine I think.

Richard.

> diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
> index bbc2e0df01d..0ae880b15bb 100644
> --- a/gcc/tree-vectorizer.h
> +++ b/gcc/tree-vectorizer.h
> @@ -1308,7 +1308,8 @@ public:
>  #define LOOP_VINFO_EARLY_BREAKS(L)         (L)->early_breaks
>  #define LOOP_VINFO_EARLY_BRK_STORES(L)     (L)->early_break_stores
>  #define LOOP_VINFO_EARLY_BREAKS_VECT_PEELED(L)  \
> -  (single_pred ((L)->loop->latch) != (L)->vec_loop_iv_exit->src)
> +  ((single_pred ((L)->loop->latch) != (L)->vec_loop_iv_exit->src) \
> +   || LOOP_VINFO_NITERS_UNCOUNTED_P (L))
>  #define LOOP_VINFO_EARLY_BREAKS_LIVE_IVS(L)  \
>    (L)->early_break_live_ivs
>  #define LOOP_VINFO_EARLY_BRK_DEST_BB(L)    (L)->early_break_dest_bb
> 

-- 
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)

Reply via email to