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

> In `vect_do_peeling' and `vect_transform_loop', there are several bits
> of logic reliant on niters that need to be handled differently in the
> case of uncounted loops.
> 
> Firstly When we peel the loop, adding a prolog,  we subtract the
> prolog peeling factor from the original number of iterations for the
> main loop.
> 
> Then, upon vectorization of the main loop, we need to update the
> iteration upper-bound to reflect the fact that each iteration now acts
> on VF elements, such that less iterations will be needed.
> 
> Both of these updates become unnecessary when we don't have an IV
> counting exit.  Therefore, it is sufficient to guard these
> manipulations behind a check for whether the loop we're dealing with
> is uncounted.

OK.

> gcc/ChangeLog:
> 
>       * tree-vect-loop-manip.cc (vect_do_peeling): Disable niters
>       update.
>       * tree-vect-loop.cc (vect_transform_loop): Likewise.
> ---
>  gcc/tree-vect-loop-manip.cc | 53 ++++++++++++++++++++-----------------
>  gcc/tree-vect-loop.cc       | 21 +++++++++------
>  2 files changed, 42 insertions(+), 32 deletions(-)
> 
> diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
> index 928045540da..18a5059251b 100644
> --- a/gcc/tree-vect-loop-manip.cc
> +++ b/gcc/tree-vect-loop-manip.cc
> @@ -3152,6 +3152,7 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, 
> tree nitersm1,
>    int estimated_vf;
>    int prolog_peeling = 0;
>    bool vect_epilogues = loop_vinfo->epilogue_vinfo != NULL;
> +  bool uncounted_p = LOOP_VINFO_NITERS_UNCOUNTED_P (loop_vinfo);
>  
>    if (!vect_use_loop_mask_for_alignment_p (loop_vinfo))
>      prolog_peeling = LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo);
> @@ -3545,36 +3546,40 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree 
> niters, tree nitersm1,
>         bb_before_epilog = loop_preheader_edge (epilog)->src;
>       }
>  
> -      /* If loop is peeled for non-zero constant times, now niters refers to
> -      orig_niters - prolog_peeling, it won't overflow even the orig_niters
> -      overflows.  */
> -      niters_no_overflow |= (prolog_peeling > 0);
> -      vect_gen_vector_loop_niters (loop_vinfo, niters,
> -                                niters_vector, step_vector,
> -                                niters_no_overflow);
> -      if (!integer_onep (*step_vector))
> +      if (!uncounted_p)
>       {
> -       /* On exit from the loop we will have an easy way of calcalating
> -          NITERS_VECTOR / STEP * STEP.  Install a dummy definition
> -          until then.  */
> -       niters_vector_mult_vf = make_ssa_name (TREE_TYPE (*niters_vector));
> -       SSA_NAME_DEF_STMT (niters_vector_mult_vf) = gimple_build_nop ();
> -       *niters_vector_mult_vf_var = niters_vector_mult_vf;
> +       /* If loop is peeled for non-zero constant times, now niters refers to
> +          orig_niters - prolog_peeling, it won't overflow even the
> +          orig_niters overflows.  */
> +       niters_no_overflow |= (prolog_peeling > 0);
> +       vect_gen_vector_loop_niters (loop_vinfo, niters,
> +                                    niters_vector, step_vector,
> +                                    niters_no_overflow);
> +       if (!integer_onep (*step_vector))
> +         {
> +           /* On exit from the loop we will have an easy way of calcalating
> +              NITERS_VECTOR / STEP * STEP.  Install a dummy definition
> +              until then.  */
> +           niters_vector_mult_vf
> +             = make_ssa_name (TREE_TYPE (*niters_vector));
> +           SSA_NAME_DEF_STMT (niters_vector_mult_vf) = gimple_build_nop ();
> +           *niters_vector_mult_vf_var = niters_vector_mult_vf;
> +         }
> +       else
> +         vect_gen_vector_loop_niters_mult_vf (loop_vinfo, *niters_vector,
> +                                              &niters_vector_mult_vf);
> +       /* Update IVs of original loop as if they were advanced by
> +          niters_vector_mult_vf steps.  */
> +       gcc_checking_assert (vect_can_advance_ivs_p (loop_vinfo));
> +       update_e = skip_vector ? e : loop_preheader_edge (epilog);
> +       if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo))
> +         update_e = single_succ_edge (LOOP_VINFO_IV_EXIT (loop_vinfo)->dest);
>       }
> -      else
> -     vect_gen_vector_loop_niters_mult_vf (loop_vinfo, *niters_vector,
> -                                          &niters_vector_mult_vf);
> -      /* Update IVs of original loop as if they were advanced by
> -      niters_vector_mult_vf steps.  */
> -      gcc_checking_assert (vect_can_advance_ivs_p (loop_vinfo));
> -      update_e = skip_vector ? e : loop_preheader_edge (epilog);
> -      if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo))
> -     update_e = single_succ_edge (LOOP_VINFO_IV_EXIT (loop_vinfo)->dest);
>  
>        /* If we have a peeled vector iteration, all exits are the same, leave 
> it
>        and so the main exit needs to be treated the same as the alternative
>        exits in that we leave their updates to vectorizable_live_operations.
> -      */
> +      */
>        if (!LOOP_VINFO_EARLY_BREAKS_VECT_PEELED (loop_vinfo))
>       vect_update_ivs_after_vectorizer (loop_vinfo, niters_vector_mult_vf,
>                                         update_e);
> diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
> index b17745cdaa1..901903cfbea 100644
> --- a/gcc/tree-vect-loop.cc
> +++ b/gcc/tree-vect-loop.cc
> @@ -11060,6 +11060,7 @@ vect_transform_loop (loop_vec_info loop_vinfo, gimple 
> *loop_vectorized_call)
>    bool check_profitability = false;
>    unsigned int th;
>    bool flat = maybe_flat_loop_profile (loop);
> +  bool uncounted_p = LOOP_VINFO_NITERS_UNCOUNTED_P (loop_vinfo);
>  
>    DUMP_VECT_SCOPE ("vec_transform_loop");
>  
> @@ -11144,7 +11145,7 @@ vect_transform_loop (loop_vec_info loop_vinfo, gimple 
> *loop_vectorized_call)
>        LOOP_VINFO_SCALAR_IV_EXIT (loop_vinfo)->dest->count = preheader->count;
>      }
>  
> -  if (niters_vector == NULL_TREE)
> +  if (niters_vector == NULL_TREE && !uncounted_p)
>      {
>        if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
>         && !LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)
> @@ -11267,13 +11268,17 @@ vect_transform_loop (loop_vec_info loop_vinfo, 
> gimple *loop_vectorized_call)
>       }
>      }
>  
> -  /* The vectorization factor is always > 1, so if we use an IV increment of 
> 1.
> -     a zero NITERS becomes a nonzero NITERS_VECTOR.  */
> -  if (integer_onep (step_vector))
> -    niters_no_overflow = true;
> -  vect_set_loop_condition (loop, LOOP_VINFO_IV_EXIT (loop_vinfo), loop_vinfo,
> -                        niters_vector, step_vector, niters_vector_mult_vf,
> -                        !niters_no_overflow);
> +  if (!uncounted_p)
> +    {
> +      /* The vectorization factor is always > 1, so if we use an IV 
> increment of
> +      1.  A zero NITERS becomes a nonzero NITERS_VECTOR.  */
> +      if (integer_onep (step_vector))
> +     niters_no_overflow = true;
> +
> +      vect_set_loop_condition (loop, LOOP_VINFO_IV_EXIT (loop_vinfo),
> +                            loop_vinfo, niters_vector, step_vector,
> +                            niters_vector_mult_vf, !niters_no_overflow);
> +    }
>  
>    unsigned int assumed_vf = vect_vf_for_cost (loop_vinfo);
>  
> 

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