> -----Original Message-----
> From: Alfie Richards <[email protected]>
> Sent: 08 August 2026 00:11
> To: [email protected]
> Cc: Alex Coplan <[email protected]>; Alice Carlotti
> <[email protected]>; [email protected];
> [email protected]; Tamar Christina <[email protected]>;
> [email protected]; [email protected]; [email protected]; Alfie
> Richards <[email protected]>
> Subject: [PATCH v2 06/13] vect: Make vect_maybe_permute_loop_masks
> optional and retargetable
> 
> Change vect_maybe_permute_loop_masks so that it can check if the
> permutation is possible without code generation.
> 
> Additionally, allow overriding of what controls to use for source and
> target.
> 
> gcc/ChangeLog:
> 
>       * tree-vect-loop-manip.cc (vect_maybe_permute_loop_masks):
>       Make the function optional and retargetable.
> ---
>  gcc/tree-vect-loop-manip.cc | 32 ++++++++++++++++++++++++--------
>  1 file changed, 24 insertions(+), 8 deletions(-)
> 
> diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
> index cee3779e37f..10fc0353078 100644
> --- a/gcc/tree-vect-loop-manip.cc
> +++ b/gcc/tree-vect-loop-manip.cc
> @@ -324,18 +324,30 @@ interleave_supported_p (vec_perm_indices
> *indices, tree vectype,
>                              *indices);
>  }
> 
> -/* Try to use permutes to define the masks in DEST_RGM using the masks
> -   in SRC_RGM, given that the former has twice as many masks as the
> -   latter.  Return true on success, adding any new statements to SEQ.  */
> +/* Check if its possible to use permutes to define the masks in DEST_RGM
> using
> +   the masks in SRC_RGM, given that the former has twice as many masks as
> the
> +   latter.  Return true on success.
> +
> +   Optionally, if SEQ is non-null add new statements for the permutation to
> SEQ.
> +   Additionally, if SRC_MASKS and DST_MASKS are defined, use these instead
> +   of the masks from SRC_RGM and DST_RGM.  */
> 
>  static bool
>  vect_maybe_permute_loop_masks (gimple_seq *seq, rgroup_controls
> *dest_rgm,
> -                            rgroup_controls *src_rgm)
> +                            rgroup_controls *src_rgm,
> +                            vec<tree> *dst_masks = NULL,
> +                            vec<tree> *src_masks = NULL)
>  {
>    tree src_masktype = src_rgm->type;
>    tree dest_masktype = dest_rgm->type;
> +  if (!src_masktype && !seq)
> +    return true;

It seems odd to return true here. So if we're checking validity, of a mark 
permute
but the mask type is unknown we say the permute is valid?

>    machine_mode src_mode = TYPE_MODE (src_masktype);
>    insn_code icode1, icode2;
> +
> +  vec<tree> src_controls = src_masks ? *src_masks : src_rgm->controls;
> +  vec<tree> dst_controls = dst_masks ? *dst_masks : dest_rgm->controls;
> +

So these are then mutually exclusive?  I would suggest instead then just make
an overload.  Change the normal function to take ` vec<tree> &dst_masks` and
have the ones taking rgroup_controls *src_rgm be an overload that just calls
the base one with src_rgm->controls.

That way the API enforces the mutual exclusivity and it's cleaner. Note also the
use of a reference to avoid unpacking the vec<> wrapper in the caller.

Thanks,
Tamar

>    if (dest_rgm->max_nscalars_per_iter <= src_rgm->max_nscalars_per_iter
>        && (icode1 = optab_handler (vec_unpacku_hi_optab,
>                                 src_mode)) != CODE_FOR_nothing
> @@ -347,10 +359,12 @@ vect_maybe_permute_loop_masks (gimple_seq
> *seq, rgroup_controls *dest_rgm,
>        machine_mode dest_mode = insn_data[icode1].operand[0].mode;
>        gcc_assert (dest_mode == insn_data[icode2].operand[0].mode);
>        tree unpack_masktype = vect_halve_mask_nunits (src_masktype,
> dest_mode);
> +      if (!seq)
> +     return true;
>        for (unsigned int i = 0; i < dest_rgm->controls.length (); ++i)
>       {
> -       tree src = src_rgm->controls[i / 2];
> -       tree dest = dest_rgm->controls[i];
> +       tree src = src_controls[i / 2];
> +       tree dest = dst_controls[i];
>         tree_code code = ((i & 1) == (BYTES_BIG_ENDIAN ? 0 : 1)
>                           ? VEC_UNPACK_HI_EXPR
>                           : VEC_UNPACK_LO_EXPR);
> @@ -375,6 +389,8 @@ vect_maybe_permute_loop_masks (gimple_seq *seq,
> rgroup_controls *dest_rgm,
>        && interleave_supported_p (&indices[0], src_masktype, 0)
>        && interleave_supported_p (&indices[1], src_masktype, 1))
>      {
> +      if (!seq)
> +     return true;
>        /* The destination requires twice as many mask bits as the source, so
>        we can use interleaving permutes to double up the number of bits.  */
>        tree masks[2];
> @@ -382,8 +398,8 @@ vect_maybe_permute_loop_masks (gimple_seq *seq,
> rgroup_controls *dest_rgm,
>       masks[i] = vect_gen_perm_mask_checked (src_masktype, indices[i]);
>        for (unsigned int i = 0; i < dest_rgm->controls.length (); ++i)
>       {
> -       tree src = src_rgm->controls[i / 2];
> -       tree dest = dest_rgm->controls[i];
> +       tree src = src_controls[i / 2];
> +       tree dest = dst_controls[i];
>         gimple *stmt = gimple_build_assign (dest, VEC_PERM_EXPR,
>                                             src, src, masks[i & 1]);
>         gimple_seq_add_stmt (seq, stmt);
> --
> 2.43.0

Reply via email to