On 08/06/2026 09:16, Tamar Christina wrote:
-----Original Message-----
From: Alfie Richards <[email protected]>
Sent: 21 May 2026 15:38
To: [email protected]
Cc: [email protected]; Tamar Christina <[email protected]>;
[email protected]; [email protected]; [email protected]; Alfie
Richards <[email protected]>
Subject: [PATCH 2/2] vect: Introduce LOOP_VINFO_IV_INCREMENT

Introduce LOOP_VINFO_IV_INCREMENT which stores the number of scalar
iterations an iteration of the vectorized loop has processed. Then
updates IV updates and reductions to use this value instead of VF.

Update IV update logic so the IV_INCREMENT can be loop-variant.

Simplify/remove SELECT_VL IV increment special cases by instead using
IV_INCREMENT.

As part of this change, the grouped load/store data pointer logic changes
from:

ADDRESS_1 = PHI <... , ADDRESS_3>
V1 = LOAD ADDRESS_1
ADDRESS_2 = ADDRESS_1 + BUMP
V2 = LOAD ADDRESS_2
ADDRESS_3 = ADDRESS_2 + BUMP

to:

ADDRESS_1 = PHI <... , ADDRESS_3>
V1 = LOAD ADDRESS_1
ADDRESS_2 = ADDRESS_1 + BUMP
V2 = LOAD ADDRESS_2

ADDRESS_3 = ADDRESS_1 + STEP * IV_INCREMENT

...

diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index cd1ea746ae4..6264e977bec 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -514,7 +514,6 @@ vect_set_loop_controls_directly (class loop *loop,
loop_vec_info loop_vinfo,
    tree ctrl_type = rgc->type;
    unsigned int nitems_per_iter = rgc->max_nscalars_per_iter * rgc->factor;
    poly_uint64 nitems_per_ctrl = TYPE_VECTOR_SUBPARTS (ctrl_type) * rgc-
factor;
-  poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
    tree length_limit = NULL_TREE;
    /* For length, we need length_limit to ensure length in range.  */
    if (!use_masks_p)
@@ -525,7 +524,11 @@ vect_set_loop_controls_directly (class loop *loop,
loop_vec_info loop_vinfo,
       of the vector loop, and the number that it should skip during the
       first iteration of the vector loop.  */
    tree nitems_total = niters;
-  tree nitems_step = build_int_cst (iv_type, vf);
+  tree nitems_vf
+    = build_int_cst (iv_type, LOOP_VINFO_VECT_FACTOR (loop_vinfo));
+  tree nitems_step
+    = gimple_convert (&loop_cond_gsi, true, GSI_SAME_STMT,
UNKNOWN_LOCATION,
+                     iv_type, LOOP_VINFO_IV_INCREMENT (loop_vinfo));
    tree nitems_skip = niters_skip;
    if (nitems_per_iter != 1)
      {
@@ -535,8 +538,11 @@ vect_set_loop_controls_directly (class loop *loop,
loop_vec_info loop_vinfo,
        tree iv_factor = build_int_cst (iv_type, nitems_per_iter);
        nitems_total = gimple_build (preheader_seq, MULT_EXPR, compare_type,
                                   nitems_total, compare_factor);
-      nitems_step = gimple_build (preheader_seq, MULT_EXPR, iv_type,
-                                 nitems_step, iv_factor);
+      nitems_vf = gimple_build (preheader_seq, MULT_EXPR, iv_type,
+                                 nitems_vf, iv_factor);
+      nitems_step
+       = gimple_build (&loop_cond_gsi, true, GSI_SAME_STMT,
UNKNOWN_LOCATION,
+                       MULT_EXPR, iv_type, nitems_step, iv_factor);
        if (nitems_skip)
        nitems_skip = gimple_build (preheader_seq, MULT_EXPR,
compare_type,
                                    nitems_skip, compare_factor);
@@ -578,22 +584,27 @@ vect_set_loop_controls_directly (class loop *loop,
loop_vec_info loop_vinfo,
                     insert_after, &index_before_incr, &index_after_incr);
          tree vectype = build_zero_cst (rgc->type);
          tree len = gimple_build (header_seq, IFN_SELECT_VL, iv_type,
-                                  index_before_incr, nitems_step,
+                                  index_before_incr, nitems_vf,
                                   vectype);
          gimple_seq_add_stmt (header_seq, gimple_build_assign (step, len));
+         /* Also set the LOOP_VINFO_IV_INCREMENT.  */
+         gassign* assign_iv_increment
+           = gimple_build_assign (LOOP_VINFO_IV_INCREMENT (loop_vinfo),
len);
+         gimple_seq_add_stmt (header_seq, assign_iv_increment);

Since this function is called for every rgroup, if you have multiple rgroups
don't you end up creating multiple defining statements here?

And also don't you need a gimple_convert? IV type can be a non-standard
integer to deal with UB on increments.  I see atm LOOP_VINFO_INCREMENT
is hardcoded to ssizetype, but I think LOOP_VINFO_RGROUP_IV_TYPE is better
for masked loops.

Hi Tamar,

This is okay because the logic around the call to vect_set_loop_controls_directly ensures that when LOOP_VINFO_USING_DECREMENTING_IV_P is true, then vect_set_loop_controls_directly is called at most once. Though the code is a little misleading.

I believe this assumption is already relied upon as there should only ever be one SELECT_VL call which is also created here.

I can change to using LOOP_VINFO_RGROUP_IV_TYPE for IV_INCREMENT as well, though I don't think it should matter for UB on increment as for all the IV's we convert the IV_INCREMENT to the IV's type before the IV increment. As the IV_INCREMENT is always a small non-negative integer it should never matter that it comes from a sizetype or any-other type.

Thanks for the review, will send V2 soon,
Alfie

Reply via email to