aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2018-01-03 08:59:18 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-01-03 08:59:18 +0000
commit6b0630fbe8c34255f2739f63a8d3e5b636020bf4 (patch)
treee12d59269ca650f27b7141a5e825d503877ad63c
parent9f61be58cec631ded93e6b71940dacd14ce3f3f5 (diff)
downloadgcc-6b0630fbe8c34255f2739f63a8d3e5b636020bf4.zip
gcc-6b0630fbe8c34255f2739f63a8d3e5b636020bf4.tar.gz
gcc-6b0630fbe8c34255f2739f63a8d3e5b636020bf4.tar.bz2
poly_int: vec_perm_indices element type
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
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/config/aarch64/aarch64.c2
-rw-r--r--gcc/fold-const.c7
-rw-r--r--gcc/int-vector-builder.h2
-rw-r--r--gcc/optabs.c10
-rw-r--r--gcc/tree-vect-generic.c11
-rw-r--r--gcc/tree-vect-slp.c6
-rw-r--r--gcc/vec-perm-indices.c17
-rw-r--r--gcc/vec-perm-indices.h18
-rw-r--r--gcc/vector-builder.h3
10 files changed, 66 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 31092fb..bc93660 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,24 @@
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>
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 21f049a..1fc57a2 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -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);
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index e2e4600..6c13d6d 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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)
diff --git a/gcc/int-vector-builder.h b/gcc/int-vector-builder.h
index c416ee0..30a8ae1 100644
--- a/gcc/int-vector-builder.h
+++ b/gcc/int-vector-builder.h
@@ -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. */
diff --git a/gcc/optabs.c b/gcc/optabs.c
index c3ee454..5706205 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -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;
}
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index 27d03a7..a9a6640 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -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;
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 391b3ea..5da3e15 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -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);
diff --git a/gcc/vec-perm-indices.c b/gcc/vec-perm-indices.c
index 8b6f412..2bcac72 100644
--- a/gcc/vec-perm-indices.c
+++ b/gcc/vec-perm-indices.c
@@ -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;
}
diff --git a/gcc/vec-perm-indices.h b/gcc/vec-perm-indices.h
index 52b65a5..0b54782 100644
--- a/gcc/vec-perm-indices.h
+++ b/gcc/vec-perm-indices.h
@@ -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
diff --git a/gcc/vector-builder.h b/gcc/vector-builder.h
index 74e0b76..939709c 100644
--- a/gcc/vector-builder.h
+++ b/gcc/vector-builder.h
@@ -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))