poly_int: vec_perm_indices element type
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 3 Jan 2018 08:59:18 +0000 (08:59 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 3 Jan 2018 08:59:18 +0000 (08:59 +0000)
This patch changes the vec_perm_indices element type from HOST_WIDE_INT
to poly_int64, so that it can represent indices into a variable-length
vector.

2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
* vec-perm-indices.h (vec_perm_builder): Change element type
from HOST_WIDE_INT to poly_int64.
(vec_perm_indices::element_type): Update accordingly.
(vec_perm_indices::clamp): Handle polynomial element_types.
* vec-perm-indices.c (vec_perm_indices::series_p): Likewise.
(vec_perm_indices::all_in_range_p): Likewise.
(tree_to_vec_perm_builder): Check for poly_int64 trees rather
than shwi trees.
* vector-builder.h (vector_builder::stepped_sequence_p): Handle
polynomial vec_perm_indices element types.
* int-vector-builder.h (int_vector_builder::equal_p): Likewise.
* fold-const.c (fold_vec_perm): Likewise.
* optabs.c (shift_amt_for_vec_perm_mask): Likewise.
* tree-vect-generic.c (lower_vec_perm): Likewise.
* tree-vect-slp.c (vect_transform_slp_perm_load): Likewise.
* config/aarch64/aarch64.c (aarch64_evpc_tbl): Cast d->perm
element type to HOST_WIDE_INT.

From-SVN: r256164

gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/fold-const.c
gcc/int-vector-builder.h
gcc/optabs.c
gcc/tree-vect-generic.c
gcc/tree-vect-slp.c
gcc/vec-perm-indices.c
gcc/vec-perm-indices.h
gcc/vector-builder.h

index 31092fbf2ae05aca8c2e73c0c67c892940cfc92b..bc93660d1af8ce8ee13fdec97abe6292e2a154ae 100644 (file)
@@ -1,3 +1,23 @@
+2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * vec-perm-indices.h (vec_perm_builder): Change element type
+       from HOST_WIDE_INT to poly_int64.
+       (vec_perm_indices::element_type): Update accordingly.
+       (vec_perm_indices::clamp): Handle polynomial element_types.
+       * vec-perm-indices.c (vec_perm_indices::series_p): Likewise.
+       (vec_perm_indices::all_in_range_p): Likewise.
+       (tree_to_vec_perm_builder): Check for poly_int64 trees rather
+       than shwi trees.
+       * vector-builder.h (vector_builder::stepped_sequence_p): Handle
+       polynomial vec_perm_indices element types.
+       * int-vector-builder.h (int_vector_builder::equal_p): Likewise.
+       * fold-const.c (fold_vec_perm): Likewise.
+       * optabs.c (shift_amt_for_vec_perm_mask): Likewise.
+       * tree-vect-generic.c (lower_vec_perm): Likewise.
+       * tree-vect-slp.c (vect_transform_slp_perm_load): Likewise.
+       * config/aarch64/aarch64.c (aarch64_evpc_tbl): Cast d->perm
+       element type to HOST_WIDE_INT.
+
 2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index 21f049a4974f5fc46412699a693c6e091108c9f8..1fc57a218b7e1aa38b4b4f1f08edc85cc999193c 100644 (file)
@@ -13625,7 +13625,7 @@ aarch64_evpc_tbl (struct expand_vec_perm_d *d)
         mode on NEON.  Reverse the index within each word but not the word
         itself.  */
       rperm[i] = GEN_INT (BYTES_BIG_ENDIAN ? d->perm[i] ^ (nunits - 1)
-                                          : d->perm[i]);
+                                          : (HOST_WIDE_INT) d->perm[i]);
     }
   sel = gen_rtx_CONST_VECTOR (vmode, gen_rtvec_v (nelt, rperm));
   sel = force_reg (vmode, sel);
index e2e46005f8cc886ec87e7fb465b03b145d97203f..6c13d6d34039c3603077b6ff3f8f92cd4939e66c 100644 (file)
@@ -8945,9 +8945,12 @@ fold_vec_perm (tree type, tree arg0, tree arg1, const vec_perm_indices &sel)
   tree_vector_builder out_elts (type, nelts, 1);
   for (i = 0; i < nelts; i++)
     {
-      if (!CONSTANT_CLASS_P (in_elts[sel[i]]))
+      HOST_WIDE_INT index;
+      if (!sel[i].is_constant (&index))
+       return NULL_TREE;
+      if (!CONSTANT_CLASS_P (in_elts[index]))
        need_ctor = true;
-      out_elts.quick_push (unshare_expr (in_elts[sel[i]]));
+      out_elts.quick_push (unshare_expr (in_elts[index]));
     }
 
   if (need_ctor)
index c416ee05bbf61e0f58747b253d45d5206daa52f1..30a8ae18321d049d70afa8abcab48125989c25d6 100644 (file)
@@ -66,7 +66,7 @@ template<typename T>
 inline bool
 int_vector_builder<T>::equal_p (T elt1, T elt2) const
 {
-  return elt1 == elt2;
+  return known_eq (elt1, elt2);
 }
 
 /* Return the value of element ELT2 minus the value of element ELT1.  */
index c3ee454f726fb97bb5faa347a5c6cdaf957708ae..5706205069e4488fdb938adf0fbca3ee733679b4 100644 (file)
@@ -5398,16 +5398,18 @@ shift_amt_for_vec_perm_mask (machine_mode mode, const vec_perm_indices &sel)
 {
   unsigned int nelt = GET_MODE_NUNITS (mode);
   unsigned int bitsize = GET_MODE_UNIT_BITSIZE (mode);
-  unsigned int first = sel[0];
-  if (first >= nelt)
+  poly_int64 first = sel[0];
+  if (maybe_ge (sel[0], nelt))
     return NULL_RTX;
 
   if (!sel.series_p (0, 1, first, 1))
     for (unsigned int i = 1; i < nelt; i++)
       {
-       unsigned int expected = i + first;
+       poly_int64 expected = i + first;
        /* Indices into the second vector are all equivalent.  */
-       if (MIN (nelt, sel[i]) != MIN (nelt, expected))
+       if (maybe_lt (sel[i], nelt)
+           ? maybe_ne (sel[i], expected)
+           : maybe_lt (expected, nelt))
          return NULL_RTX;
       }
 
index 27d03a7262fac90993fe61e44dd6ba882a37fbe4..a9a6640687b767a3d88e4d53c66cfa43666efe7d 100644 (file)
@@ -1337,18 +1337,19 @@ lower_vec_perm (gimple_stmt_iterator *gsi)
          != CODE_FOR_nothing
          && TREE_CODE (vec1) == VECTOR_CST
          && initializer_zerop (vec1)
-         && indices[0]
-         && indices[0] < elements)
+         && maybe_ne (indices[0], 0)
+         && known_lt (indices[0], elements))
        {
          bool ok_p = indices.series_p (0, 1, indices[0], 1);
          if (!ok_p)
            {
              for (i = 1; i < elements; ++i)
                {
-                 unsigned int expected = i + indices[0];
+                 poly_int64 expected = i + indices[0];
                  /* Indices into the second vector are all equivalent.  */
-                 if (MIN (elements, (unsigned) indices[i])
-                     != MIN (elements, expected))
+                 if (maybe_lt (indices[i], elements)
+                     ? maybe_ne (indices[i], expected)
+                     : maybe_lt (expected, elements))
                    break;
                }
              ok_p = i == elements;
index 391b3ea1d8836fe31a1b80bc3ef7b74c173b96ed..5da3e156d5dd2b8cb0c6ed034a43174c7c9fe484 100644 (file)
@@ -3727,8 +3727,10 @@ vect_transform_slp_perm_load (slp_tree node, vec<tree> dr_chain,
                                       vect_location, 
                                       "unsupported vect permute { ");
                      for (i = 0; i < nunits; ++i)
-                       dump_printf (MSG_MISSED_OPTIMIZATION,
-                                    HOST_WIDE_INT_PRINT_DEC " ", mask[i]);
+                       {
+                         dump_dec (MSG_MISSED_OPTIMIZATION, mask[i]);
+                         dump_printf (MSG_MISSED_OPTIMIZATION, " ");
+                       }
                      dump_printf (MSG_MISSED_OPTIMIZATION, "}\n");
                    }
                  gcc_assert (analyze_only);
index 8b6f412ba5fee0bfd418df5e3f368b2cb84badb1..2bcac72e5a899c26a96c66d6d43fdbe725e4ea98 100644 (file)
@@ -95,7 +95,7 @@ vec_perm_indices::series_p (unsigned int out_base, unsigned int out_step,
                            element_type in_base, element_type in_step) const
 {
   /* Check the base value.  */
-  if (clamp (m_encoding.elt (out_base)) != clamp (in_base))
+  if (maybe_ne (clamp (m_encoding.elt (out_base)), clamp (in_base)))
     return false;
 
   unsigned int full_nelts = m_encoding.full_nelts ();
@@ -127,7 +127,7 @@ vec_perm_indices::series_p (unsigned int out_base, unsigned int out_step,
 
       element_type v0 = m_encoding.elt (out_base - out_step);
       element_type v1 = m_encoding.elt (out_base);
-      if (clamp (v1 - v0) != in_step)
+      if (maybe_ne (clamp (v1 - v0), in_step))
        return false;
 
       out_base += out_step;
@@ -146,7 +146,7 @@ vec_perm_indices::all_in_range_p (element_type start, element_type size) const
   unsigned int nelts_per_pattern = m_encoding.nelts_per_pattern ();
   unsigned int base_nelts = npatterns * MIN (nelts_per_pattern, 2);
   for (unsigned int i = 0; i < base_nelts; ++i)
-    if (m_encoding[i] < start || (m_encoding[i] - start) >= size)
+    if (!known_in_range_p (m_encoding[i], start, size))
       return false;
 
   /* For stepped encodings, check the full range of the series.  */
@@ -174,8 +174,11 @@ vec_perm_indices::all_in_range_p (element_type start, element_type size) const
             wide enough for overflow not to be a problem.  */
          element_type headroom_down = base1 - start;
          element_type headroom_up = size - headroom_down - 1;
-         if (headroom_up < step * step_nelts
-             && headroom_down < (limit - step) * step_nelts)
+         HOST_WIDE_INT diff;
+         if ((!step.is_constant (&diff)
+              || maybe_lt (headroom_up, diff * step_nelts))
+             && (!(limit - step).is_constant (&diff)
+                 || maybe_lt (headroom_down, diff * step_nelts)))
            return false;
        }
     }
@@ -191,14 +194,14 @@ tree_to_vec_perm_builder (vec_perm_builder *builder, tree cst)
 {
   unsigned int encoded_nelts = vector_cst_encoded_nelts (cst);
   for (unsigned int i = 0; i < encoded_nelts; ++i)
-    if (!tree_fits_shwi_p (VECTOR_CST_ENCODED_ELT (cst, i)))
+    if (!tree_fits_poly_int64_p (VECTOR_CST_ENCODED_ELT (cst, i)))
       return false;
 
   builder->new_vector (TYPE_VECTOR_SUBPARTS (TREE_TYPE (cst)),
                       VECTOR_CST_NPATTERNS (cst),
                       VECTOR_CST_NELTS_PER_PATTERN (cst));
   for (unsigned int i = 0; i < encoded_nelts; ++i)
-    builder->quick_push (tree_to_shwi (VECTOR_CST_ENCODED_ELT (cst, i)));
+    builder->quick_push (tree_to_poly_int64 (VECTOR_CST_ENCODED_ELT (cst, i)));
   return true;
 }
 
index 52b65a51e4b1830582e8fb36d1c19b038efd8161..0b5478207113e14bd7f656fa14efc0422e729544 100644 (file)
@@ -25,7 +25,7 @@ along with GCC; see the file COPYING3.  If not see
 /* A vector_builder for building constant permutation vectors.
    The elements do not need to be clamped to a particular range
    of input elements.  */
-typedef int_vector_builder<HOST_WIDE_INT> vec_perm_builder;
+typedef int_vector_builder<poly_int64> vec_perm_builder;
 
 /* This class represents a constant permutation vector, such as that used
    as the final operand to a VEC_PERM_EXPR.
@@ -49,7 +49,7 @@ typedef int_vector_builder<HOST_WIDE_INT> vec_perm_builder;
    different numbers of elements.  */
 class vec_perm_indices
 {
-  typedef HOST_WIDE_INT element_type;
+  typedef poly_int64 element_type;
 
 public:
   vec_perm_indices ();
@@ -118,13 +118,17 @@ vec_perm_indices::vec_perm_indices (const vec_perm_builder &elements,
 inline vec_perm_indices::element_type
 vec_perm_indices::clamp (element_type elt) const
 {
-  element_type limit = input_nelts ();
-  elt %= limit;
+  element_type limit = input_nelts (), elem_within_input;
+  int input;
+  if (!can_div_trunc_p (elt, limit, &input, &elem_within_input))
+    return elt;
+
   /* Treat negative elements as counting from the end.  This only matters
      if the vector size is not a power of 2.  */
-  if (elt < 0)
-    elt += limit;
-  return elt;
+  if (known_lt (elem_within_input, 0))
+    return elem_within_input + limit;
+
+  return elem_within_input;
 }
 
 /* Return the value of vector element I, which might or might not be
index 74e0b7655adc1c50b2c33fd8e9dc98692bd10718..939709ca5820faa2ffc743d1fb0a579655c8c845 100644 (file)
@@ -284,7 +284,8 @@ vector_builder<T, Derived>::stepped_sequence_p (unsigned int start,
          || !derived ()->integral_p (elt3))
        return false;
 
-      if (derived ()->step (elt1, elt2) != derived ()->step (elt2, elt3))
+      if (maybe_ne (derived ()->step (elt1, elt2),
+                   derived ()->step (elt2, elt3)))
        return false;
 
       if (!derived ()->can_elide_p (elt3))