https://gcc.gnu.org/g:3915e1c62e9a19dfdffbed283d2fc2447af4e7f3

commit r17-5001-g3915e1c62e9a19dfdffbed283d2fc2447af4e7f3
Author: Alfie Richards <[email protected]>
Date:   Thu Jun 18 13:16:56 2026 +0000

    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.
            (vect_maybe_permute_loop_masks):
            New overload.

Diff:
---
 gcc/tree-vect-loop-manip.cc | 45 ++++++++++++++++++++++++++++++++++-----------
 1 file changed, 34 insertions(+), 11 deletions(-)

diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index bbaa11e03e0f..385353bda2ba 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -324,18 +324,28 @@ 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)
+vect_maybe_permute_loop_masks (gimple_seq *seq,
+                              rgroup_controls *dest_rgm,
+                              rgroup_controls *src_rgm,
+                              vec<tree> dst_controls,
+                              vec<tree> src_controls)
 {
   tree src_masktype = src_rgm->type;
   tree dest_masktype = dest_rgm->type;
+  if (!src_masktype && !seq)
+    return false;
   machine_mode src_mode = TYPE_MODE (src_masktype);
   insn_code icode1, icode2;
+
   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 +357,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);
-      for (unsigned int i = 0; i < dest_rgm->controls.length (); ++i)
+      if (!seq)
+       return true;
+      for (unsigned int i = 0; i < dst_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,15 +387,17 @@ 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];
       for (unsigned int i = 0; i < 2; ++i)
        masks[i] = vect_gen_perm_mask_checked (src_masktype, indices[i]);
-      for (unsigned int i = 0; i < dest_rgm->controls.length (); ++i)
+      for (unsigned int i = 0; i < dst_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);
@@ -393,6 +407,15 @@ vect_maybe_permute_loop_masks (gimple_seq *seq, 
rgroup_controls *dest_rgm,
   return false;
 }
 
+static bool
+vect_maybe_permute_loop_masks (gimple_seq *seq,
+                              rgroup_controls *dest_rgm,
+                              rgroup_controls *src_rgm)
+{
+  return vect_maybe_permute_loop_masks (seq, dest_rgm, src_rgm,
+                                       dest_rgm->controls, src_rgm->controls);
+}
+
 /* Populate DEST_RGM->controls, given that they should add up to STEP.
 
      STEP = MIN_EXPR <ivtmp_34, VF>;

Reply via email to