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.

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