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.

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



Reply via email to