aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2019-07-29 08:42:19 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-07-29 08:42:19 +0000
commit708cc6132bb374e2c5bd1c4f43f9fe7306d20970 (patch)
tree97cf7a6d5112e03267943b02aaf4d57e97afb6ef
parent4ce6ab6889446984fd7017e2150962eb4550a7ee (diff)
downloadgcc-708cc6132bb374e2c5bd1c4f43f9fe7306d20970.zip
gcc-708cc6132bb374e2c5bd1c4f43f9fe7306d20970.tar.gz
gcc-708cc6132bb374e2c5bd1c4f43f9fe7306d20970.tar.bz2
Generalise VEC_DUPLICATE folding for variable-length vectors
This patch uses the constant vector encoding scheme to handle more cases of a VEC_DUPLICATE of another vector. Duplicating any fixed-length vector is fine, and duplicating a variable-length vector is OK as long as that vector is also a duplicate of a fixed-length sequence. Other cases fell through to: if (VECTOR_MODE_P (mode) && GET_CODE (op) == CONST_VECTOR) which was only expecting to deal with elementwise operations. 2019-07-29 Richard Sandiford <richard.sandiford@arm.com> gcc/ * simplify-rtx.c (simplify_const_unary_operation): Fold a VEC_DUPLICATE of a fixed-length vector even if the result is variable-length. Likewise fold a duplicate of a variable-length vector if the variable-length vector is itself a duplicate of a fixed-length sequence. (test_vector_ops_duplicate): Test more cases. From-SVN: r273868
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/simplify-rtx.c39
2 files changed, 35 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d80cd31..706939c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,14 @@
2019-07-29 Richard Sandiford <richard.sandiford@arm.com>
+ * simplify-rtx.c (simplify_const_unary_operation): Fold a
+ VEC_DUPLICATE of a fixed-length vector even if the result
+ is variable-length. Likewise fold a duplicate of a
+ variable-length vector if the variable-length vector is
+ itself a duplicate of a fixed-length sequence.
+ (test_vector_ops_duplicate): Test more cases.
+
+2019-07-29 Richard Sandiford <richard.sandiford@arm.com>
+
* vector-builder.h (vector_builder): Add a shape template parameter.
(vector_builder::new_unary_operation): New function, generalizing
the old tree_vector_builder function.
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 0a69c05..9359a3c 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -1736,23 +1736,24 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
}
if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
return gen_const_vec_duplicate (mode, op);
- unsigned int n_elts;
if (GET_CODE (op) == CONST_VECTOR
- && GET_MODE_NUNITS (mode).is_constant (&n_elts))
- {
- /* This must be constant if we're duplicating it to a constant
- number of elements. */
- unsigned int in_n_elts = CONST_VECTOR_NUNITS (op).to_constant ();
- gcc_assert (in_n_elts < n_elts);
- gcc_assert ((n_elts % in_n_elts) == 0);
- rtvec v = rtvec_alloc (n_elts);
- for (unsigned i = 0; i < n_elts; i++)
- RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op, i % in_n_elts);
- return gen_rtx_CONST_VECTOR (mode, v);
+ && (CONST_VECTOR_DUPLICATE_P (op)
+ || CONST_VECTOR_NUNITS (op).is_constant ()))
+ {
+ unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
+ ? CONST_VECTOR_NPATTERNS (op)
+ : CONST_VECTOR_NUNITS (op).to_constant ());
+ gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
+ rtx_vector_builder builder (mode, npatterns, 1);
+ for (unsigned i = 0; i < npatterns; i++)
+ builder.quick_push (CONST_VECTOR_ELT (op, i));
+ return builder.build ();
}
}
- if (VECTOR_MODE_P (mode) && GET_CODE (op) == CONST_VECTOR)
+ if (VECTOR_MODE_P (mode)
+ && GET_CODE (op) == CONST_VECTOR
+ && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
{
gcc_assert (GET_MODE (op) == op_mode);
@@ -6977,6 +6978,18 @@ test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
&& mode_for_vector (inner_mode, 2).exists (&narrower_mode)
&& VECTOR_MODE_P (narrower_mode))
{
+ /* Test VEC_DUPLICATE of a vector. */
+ rtx_vector_builder nbuilder (narrower_mode, 2, 1);
+ nbuilder.quick_push (const0_rtx);
+ nbuilder.quick_push (const1_rtx);
+ rtx_vector_builder builder (mode, 2, 1);
+ builder.quick_push (const0_rtx);
+ builder.quick_push (const1_rtx);
+ ASSERT_RTX_EQ (builder.build (),
+ simplify_unary_operation (VEC_DUPLICATE, mode,
+ nbuilder.build (),
+ narrower_mode));
+
/* Test VEC_SELECT of a vector. */
rtx vec_par
= gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));