Re: [6/n] Use build_vector_type_for_mode in get_vectype_for_scalar_type_and_size

2019-10-30 Thread Richard Biener
On Fri, Oct 25, 2019 at 2:32 PM Richard Sandiford
 wrote:
>
> Except for one case, get_vectype_for_scalar_type_and_size calculates
> what the vector mode should be and then calls build_vector_type,
> which recomputes the mode from scratch.  This patch makes it use
> build_vector_type_for_mode instead.
>
> The exception mentioned above is when preferred_simd_mode returns
> an integer mode, which it does if no appropriate vector mode exists.
> The integer mode in question is usually word_mode, although epiphany
> can return a doubleword mode in some cases.
>
> There's no guarantee that this integer mode is appropriate, since for
> example the scalar type could be a float.  The traditional behaviour is
> therefore to use the integer mode to determine a size only, and leave
> mode_for_vector to pick the TYPE_MODE.  (Note that it can actually end
> up picking a vector mode if the target defines a disabled vector mode.
> We therefore still need to check TYPE_MODE after building the type.)

OK.

Thanks,
Richard.

>
> 2019-10-24  Richard Sandiford  
>
> gcc/
> * tree-vect-stmts.c (get_vectype_for_scalar_type_and_size): If
> targetm.vectorize.preferred_simd_mode returns an integer mode,
> use mode_for_vector to decide what the vector type's mode
> should actually be.  Use build_vector_type_for_mode instead
> of build_vector_type.
>
> Index: gcc/tree-vect-stmts.c
> ===
> --- gcc/tree-vect-stmts.c   2019-10-25 13:26:59.309877555 +0100
> +++ gcc/tree-vect-stmts.c   2019-10-25 13:27:08.653811531 +0100
> @@ -11162,16 +11162,31 @@ get_vectype_for_scalar_type_and_size (tr
>/* If no size was supplied use the mode the target prefers.   Otherwise
>   lookup a vector mode of the specified size.  */
>if (known_eq (size, 0U))
> -simd_mode = targetm.vectorize.preferred_simd_mode (inner_mode);
> +{
> +  simd_mode = targetm.vectorize.preferred_simd_mode (inner_mode);
> +  if (SCALAR_INT_MODE_P (simd_mode))
> +   {
> + /* Traditional behavior is not to take the integer mode
> +literally, but simply to use it as a way of determining
> +the vector size.  It is up to mode_for_vector to decide
> +what the TYPE_MODE should be.
> +
> +Note that nunits == 1 is allowed in order to support single
> +element vector types.  */
> + if (!multiple_p (GET_MODE_SIZE (simd_mode), nbytes, )
> + || !mode_for_vector (inner_mode, nunits).exists (_mode))
> +   return NULL_TREE;
> +   }
> +}
>else if (!multiple_p (size, nbytes, )
>|| !mode_for_vector (inner_mode, nunits).exists (_mode))
>  return NULL_TREE;
> -  /* NOTE: nunits == 1 is allowed to support single element vector types.  */
> -  if (!multiple_p (GET_MODE_SIZE (simd_mode), nbytes, ))
> -return NULL_TREE;
>
> -  vectype = build_vector_type (scalar_type, nunits);
> +  vectype = build_vector_type_for_mode (scalar_type, simd_mode);
>
> +  /* In cases where the mode was chosen by mode_for_vector, check that
> + the target actually supports the chosen mode, or that it at least
> + allows the vector mode to be replaced by a like-sized integer.  */
>if (!VECTOR_MODE_P (TYPE_MODE (vectype))
>&& !INTEGRAL_MODE_P (TYPE_MODE (vectype)))
>  return NULL_TREE;


[6/n] Use build_vector_type_for_mode in get_vectype_for_scalar_type_and_size

2019-10-25 Thread Richard Sandiford
Except for one case, get_vectype_for_scalar_type_and_size calculates
what the vector mode should be and then calls build_vector_type,
which recomputes the mode from scratch.  This patch makes it use
build_vector_type_for_mode instead.

The exception mentioned above is when preferred_simd_mode returns
an integer mode, which it does if no appropriate vector mode exists.
The integer mode in question is usually word_mode, although epiphany
can return a doubleword mode in some cases.

There's no guarantee that this integer mode is appropriate, since for
example the scalar type could be a float.  The traditional behaviour is
therefore to use the integer mode to determine a size only, and leave
mode_for_vector to pick the TYPE_MODE.  (Note that it can actually end
up picking a vector mode if the target defines a disabled vector mode.
We therefore still need to check TYPE_MODE after building the type.)


2019-10-24  Richard Sandiford  

gcc/
* tree-vect-stmts.c (get_vectype_for_scalar_type_and_size): If
targetm.vectorize.preferred_simd_mode returns an integer mode,
use mode_for_vector to decide what the vector type's mode
should actually be.  Use build_vector_type_for_mode instead
of build_vector_type.

Index: gcc/tree-vect-stmts.c
===
--- gcc/tree-vect-stmts.c   2019-10-25 13:26:59.309877555 +0100
+++ gcc/tree-vect-stmts.c   2019-10-25 13:27:08.653811531 +0100
@@ -11162,16 +11162,31 @@ get_vectype_for_scalar_type_and_size (tr
   /* If no size was supplied use the mode the target prefers.   Otherwise
  lookup a vector mode of the specified size.  */
   if (known_eq (size, 0U))
-simd_mode = targetm.vectorize.preferred_simd_mode (inner_mode);
+{
+  simd_mode = targetm.vectorize.preferred_simd_mode (inner_mode);
+  if (SCALAR_INT_MODE_P (simd_mode))
+   {
+ /* Traditional behavior is not to take the integer mode
+literally, but simply to use it as a way of determining
+the vector size.  It is up to mode_for_vector to decide
+what the TYPE_MODE should be.
+
+Note that nunits == 1 is allowed in order to support single
+element vector types.  */
+ if (!multiple_p (GET_MODE_SIZE (simd_mode), nbytes, )
+ || !mode_for_vector (inner_mode, nunits).exists (_mode))
+   return NULL_TREE;
+   }
+}
   else if (!multiple_p (size, nbytes, )
   || !mode_for_vector (inner_mode, nunits).exists (_mode))
 return NULL_TREE;
-  /* NOTE: nunits == 1 is allowed to support single element vector types.  */
-  if (!multiple_p (GET_MODE_SIZE (simd_mode), nbytes, ))
-return NULL_TREE;
 
-  vectype = build_vector_type (scalar_type, nunits);
+  vectype = build_vector_type_for_mode (scalar_type, simd_mode);
 
+  /* In cases where the mode was chosen by mode_for_vector, check that
+ the target actually supports the chosen mode, or that it at least
+ allows the vector mode to be replaced by a like-sized integer.  */
   if (!VECTOR_MODE_P (TYPE_MODE (vectype))
   && !INTEGRAL_MODE_P (TYPE_MODE (vectype)))
 return NULL_TREE;