On Fri, Nov 13, 2026 at 12:45 PM Richard Earnshaw via Sourceware Forge
<[email protected]> wrote:
>
> From: Richard Earnshaw <[email protected]>
>
> If a vec_perm selects the same element from the source for every
> element in the destination, eg with
>   __builtin_shuffle (v1, v2, { N, N,... N });
> then this can be simplified to
>   vec_duplicate (v[N'])
> where v and N' are picked from the first vector or the second depending
> on the value of N.

ISTR we sofar refrained from using VEC_DUPLICATE for non-VLA vectors
for reasons that escape me.  Is this to have vec_same_elem_p handle
the permute case?  Can we instead handle a canonical vec_permute
form there (and in uniform_vector_p)?

> gcc/ChangeLog:
>
>         * match.pd: Simplify vec_perm to vec_duplicate when all outputs
>         come from the same input lane.
> ---
>  gcc/match.pd | 24 +++++++++++++++++++++++-
>  1 file changed, 23 insertions(+), 1 deletion(-)
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 3912f9f7d5438..52ebf642677e8 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -12910,6 +12910,28 @@ and,
>       (view_convert @0)
>       (if (known_eq (nelts, nelts_in) && sel.series_p (0, 1, nelts_in, 1))
>        (view_convert @1)
> +      (if (canonicalize_math_after_vectorization_p ()
> +          && known_eq (nelts, nelts_in) && sel.series_p (0, 1, sel[0], 0)
> +          && (known_lt ((poly_uint64) sel[0], nelts)
> +              || known_ge ((poly_uint64) sel[0], nelts)))
> +       (with
> +       {
> +         poly_uint64 index = sel[0];
> +         tree vec = op0;
> +         poly_uint64 lane = index;
> +         if (known_ge (index, nelts))
> +           {
> +             vec = op1;
> +             lane -= nelts;
> +           }
> +         tree elem_type = TREE_TYPE (TREE_TYPE (vec));
> +         unsigned HOST_WIDE_INT bits = tree_to_uhwi (TYPE_SIZE (elem_type));
> +       }
> +       (
> +         vec_duplicate
> +          (BIT_FIELD_REF:elem_type { vec; }
> +                                   { bitsize_int (bits); }
> +                                   { bitsize_int (lane * bits); })))
>        (with
>         {
>           if (!single_arg)
> @@ -13022,7 +13044,7 @@ and,
>           (bit_insert { op0; } { ins; }
>            { bitsize_int (at * vector_element_bits (type)); })
>           (if (changed)
> -          (vec_perm { op0; } { op1; } { op2; }))))))))))))
> +          (vec_perm { op0; } { op1; } { op2; })))))))))))))
>
>  /* VEC_PERM_EXPR (v, v, mask) -> v where v contains same element.  */
>
> --
> 2.56.0
>

Reply via email to