diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2019-07-29 08:42:19 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2019-07-29 08:42:19 +0000 |
commit | 708cc6132bb374e2c5bd1c4f43f9fe7306d20970 (patch) | |
tree | 97cf7a6d5112e03267943b02aaf4d57e97afb6ef | |
parent | 4ce6ab6889446984fd7017e2150962eb4550a7ee (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/simplify-rtx.c | 39 |
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)); |