On Tue, 18 Nov 2025, Victor Do Nascimento wrote:

> 
> 
> On 11/11/25 08:46, Richard Biener wrote:
> > 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?
> 
> When you talk about re-ordering the test below, are you asking what
> would happen if we were to guard the population of the IV_EXIT field
> with `if (!LOOP_VINFO_NITERS_UNCOUNTED_P)' too?
> 
> There is an expectation that the exit in LOOP_VINFO_IV_EXIT is the
> main exit, disconnected from whether or not it is a counted IV exit.
> 
> As such, it has many uses even in the context of uncounted loops that
> would break, were we to leave it empty (assuming I understood your
> question correctly... My apologies if I misunderstood you).
> 
> 
> > I guess eventually renaming it to LOOP_VINFO_MAIN_EXIT would be
> > another option.
> 
> If you've no objection to my doing so, I will add this change as one
> of my patches for V2 of this patch series. I think this would be
> very useful in the context of clarifying the expanded scope of how
> LOOP_VINFO_MAIN_EXIT is now used in the vectorizer.

I think my question was exactly that - formerly the IV_EXIT was
counted, but if consumers exist that do not care about the countedness
then we should indeed rename it and adjust documentation.

Richard.

> Many thanks,
> Victor
> > 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