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)
