Message ID | 541ACFC7.2050901@arm.com |
---|---|
State | New |
Headers | show |
On Thu, Sep 18, 2014 at 2:27 PM, Alan Lawrence <alan.lawrence@arm.com> wrote: > The VEC_RSHIFT_EXPR is only ever used by the vectorizer in tree-vect-loop.c > (vect_create_epilog_for_reduction), to shift the vector by a whole number of > elements. The tree code allows more general shifts but only for integral > types. This only causes pain and difficulty for backends (particularly for > backends with different endiannesses), and enforcing that restriction for > integral types too does no harm. > > bootstrapped on aarch64-none-linux-gnu and x86-64-none-linux-gnu > check-gcc on aarch64-none-elf and x86_64-none-linux-gnu Hmm, but then (coming from the tree / gimple level) all shifts can be expressed with a VEC_PERM_EXPR. And of course a general whole-vector shift could be expressed using a VIEW_CONVERT_EXPR to a 1-element integer vector and a regular [RL]SHIFT_EXPR and then converting back. So it seems to me that the vectorizer should instead emit a VEC_PERM_EXPR (making sure the backends or the generic vec_perm expansion code in optabs.c handles the whole-vector-shift case in an optimal way). The current VEC_RSHIFT_EXPR description lacks information on what is shifted in btw (always zeros? the most significant bit (endian dependent?!)). So - can we instead remove VEC_[LR]SHIFT_EXPR? Seems that VEC_LSHIFT_EXPR is unused anyway, and thus vec_shl_optabs as well. Thanks, Richard. > gcc/ChangeLog: > > * tree-cfg.c (verify_gimple_assign_binary): for VEC_RSHIFT_EXPR (and > VEC_LSHIFT_EXPR), require shifts to be by a whole number of elements > for all types, rather than only non-integral types. > > * tree.def (VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR): Update comment. > > * doc/md.texi (vec_shl_m, vec_shr_m): Update comment. >
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 3f5fd6f0e3ac3fcc30f6c961e3e2709a35f4d413..a78aea2f3f6e35b0d89719a42d734e62a2f5bd65 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -4888,7 +4888,8 @@ of a wider mode.) @item @samp{vec_shl_@var{m}}, @samp{vec_shr_@var{m}} Whole vector left/right shift in bits. Operand 1 is a vector to be shifted. -Operand 2 is an integer shift amount in bits. +Operand 2 is an integer shift amount in bits, which must be a multiple of the +element size. Operand 0 is where the resulting shifted vector is stored. The output and input vectors should have the same modes. diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 49986cc40758bb5998e395c727142e75f7d6e9f4..1ea2e256b09b25331810a57a9c35e5cc875d0404 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -3667,14 +3667,11 @@ verify_gimple_assign_binary (gimple stmt) debug_generic_expr (rhs2_type); return true; } - /* For shifting a vector of non-integral components we - only allow shifting by a constant multiple of the element size. */ - if (!INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type)) - && (TREE_CODE (rhs2) != INTEGER_CST - || !div_if_zero_remainder (rhs2, - TYPE_SIZE (TREE_TYPE (rhs1_type))))) + /* All shifts must be by a constant multiple of the element size. */ + if (TREE_CODE (rhs2) != INTEGER_CST + || !div_if_zero_remainder (rhs2, TYPE_SIZE (TREE_TYPE (rhs1_type)))) { - error ("non-element sized vector shift of floating point vector"); + error ("non-element sized vector shift"); return true; } diff --git a/gcc/tree.def b/gcc/tree.def index e9af52e554babb100d49ea14f47c805cd5024949..5406ffe67c53ff3f12920ca8c965cf0740a079c2 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -1240,7 +1240,8 @@ DEFTREECODE (FMA_EXPR, "fma_expr", tcc_expression, 3) /* Whole vector left/right shift in bits. Operand 0 is a vector to be shifted. - Operand 1 is an integer shift amount in bits. */ + Operand 1 is an integer shift amount in bits, which must be a multiple of the + element size. */ DEFTREECODE (VEC_LSHIFT_EXPR, "vec_lshift_expr", tcc_binary, 2) DEFTREECODE (VEC_RSHIFT_EXPR, "vec_rshift_expr", tcc_binary, 2)