On Fri, Oct 25, 2019 at 2:32 PM Richard Sandiford <richard.sandif...@arm.com> 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 <richard.sandif...@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. > > 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, &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;