diff mbox

[9/14] Enforce whole-vector-shifts to always be by a whole number of elements

Message ID 541ACFC7.2050901@arm.com
State New
Headers show

Commit Message

Alan Lawrence Sept. 18, 2014, 12:27 p.m. UTC
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

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.

Comments

Richard Biener Sept. 22, 2014, 10:50 a.m. UTC | #1
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 mbox

Patch

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)