Use build_vector_type_for_mode in get_vectype_for_scalar_type_and_size
authorRichard Sandiford <richard.sandiford@arm.com>
Thu, 14 Nov 2019 14:57:26 +0000 (14:57 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 14 Nov 2019 14:57:26 +0000 (14:57 +0000)
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-11-14  Richard Sandiford  <richard.sandiford@arm.com>

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.

From-SVN: r278234

gcc/ChangeLog
gcc/tree-vect-stmts.c

index 48f5f37..210a9c4 100644 (file)
@@ -1,5 +1,13 @@
 2019-11-14  Richard Sandiford  <richard.sandiford@arm.com>
 
+       * 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.
+
+2019-11-14  Richard Sandiford  <richard.sandiford@arm.com>
+
        * target.def (get_mask_mode): Take a vector mode itself as argument,
        instead of properties about the vector mode.
        * doc/tm.texi: Regenerate.
index 71c635c..9361a23 100644 (file)
@@ -11176,16 +11176,31 @@ get_vectype_for_scalar_type_and_size (tree scalar_type, poly_uint64 size)
   /* 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, &nunits)
+             || !mode_for_vector (inner_mode, nunits).exists (&simd_mode))
+           return NULL_TREE;
+       }
+    }
   else if (!multiple_p (size, nbytes, &nunits)
           || !mode_for_vector (inner_mode, nunits).exists (&simd_mode))
     return NULL_TREE;
-  /* NOTE: nunits == 1 is allowed to support single element vector types.  */
-  if (!multiple_p (GET_MODE_SIZE (simd_mode), nbytes, &nunits))
-    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;