From 95da266b86fcdeff84fcadc5e3cde3d0027e571d Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 14 Nov 2019 14:57:26 +0000 Subject: [PATCH] Use build_vector_type_for_mode in get_vectype_for_scalar_type_and_size 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 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 | 8 ++++++++ gcc/tree-vect-stmts.c | 25 ++++++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 48f5f37ee0d..210a9c4f4ab 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-11-14 Richard Sandiford + + * 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 * target.def (get_mask_mode): Take a vector mode itself as argument, diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 71c635c57b9..9361a23785e 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -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; -- 2.30.2