This patch passes the data vector mode to get_mask_mode, rather than its size and nunits. This is a bit simpler and allows targets to distinguish between modes that happen to have the same size and number of elements.
Tested individually on aarch64-linux-gnu and as a series on x86_64-linux-gnu. OK to install? Richard 2019-10-23 Richard Sandiford <richard.sandif...@arm.com> gcc/ * target.def (get_mask_mode): Take a vector mode itself as argument, instead of properties about the vector mode. * doc/tm.texi: Regenerate. * targhooks.h (default_get_mask_mode): Update to reflect new get_mode_mask interface. * targhooks.c (default_get_mask_mode): Likewise. Use related_int_vector_mode. * optabs-query.c (can_vec_mask_load_store_p): Update call to get_mask_mode. * tree-vect-stmts.c (check_load_store_masking): Likewise, checking first that the original mode really is a vector. * tree.c (build_truth_vector_type_for): Likewise. * config/aarch64/aarch64.c (aarch64_get_mask_mode): Update for new get_mode_mask interface. (aarch64_expand_sve_vcond): Update call accordingly. * config/gcn/gcn.c (gcn_vectorize_get_mask_mode): Update for new get_mode_mask interface. * config/i386/i386.c (ix86_get_mask_mode): Likewise. Index: gcc/target.def =================================================================== --- gcc/target.def 2019-10-23 11:33:01.568510253 +0100 +++ gcc/target.def 2019-10-23 12:13:54.099122100 +0100 @@ -1939,17 +1939,17 @@ when @var{nunits} is zero. This is the /* Function to get a target mode for a vector mask. */ DEFHOOK (get_mask_mode, - "A vector mask is a value that holds one boolean result for every element\n\ -in a vector. This hook returns the machine mode that should be used to\n\ -represent such a mask when the vector in question is @var{length} bytes\n\ -long and contains @var{nunits} elements. The hook returns an empty\n\ -@code{opt_machine_mode} if no such mode exists.\n\ + "Return the mode to use for a vector mask that holds one boolean\n\ +result for each element of vector mode @var{mode}. The returned mask mode\n\ +can be a vector of integers (class @code{MODE_VECTOR_INT}), a vector of\n\ +booleans (class @code{MODE_VECTOR_BOOL}) or a scalar integer (class\n\ +@code{MODE_INT}). Return an empty @code{opt_machine_mode} if no such\n\ +mask mode exists.\n\ \n\ -The default implementation returns the mode of an integer vector that\n\ -is @var{length} bytes long and that contains @var{nunits} elements,\n\ -if such a mode exists.", +The default implementation returns a @code{MODE_VECTOR_INT} with the\n\ +same size and number of elements as @var{mode}, if such a mode exists.", opt_machine_mode, - (poly_uint64 nunits, poly_uint64 length), + (machine_mode mode), default_get_mask_mode) /* Function to say whether a masked operation is expensive when the Index: gcc/doc/tm.texi =================================================================== --- gcc/doc/tm.texi 2019-10-23 11:33:01.560510309 +0100 +++ gcc/doc/tm.texi 2019-10-23 12:13:54.099122100 +0100 @@ -6053,16 +6053,16 @@ requested mode, returning a mode with th when @var{nunits} is zero. This is the correct behavior for most targets. @end deftypefn -@deftypefn {Target Hook} opt_machine_mode TARGET_VECTORIZE_GET_MASK_MODE (poly_uint64 @var{nunits}, poly_uint64 @var{length}) -A vector mask is a value that holds one boolean result for every element -in a vector. This hook returns the machine mode that should be used to -represent such a mask when the vector in question is @var{length} bytes -long and contains @var{nunits} elements. The hook returns an empty -@code{opt_machine_mode} if no such mode exists. +@deftypefn {Target Hook} opt_machine_mode TARGET_VECTORIZE_GET_MASK_MODE (machine_mode @var{mode}) +Return the mode to use for a vector mask that holds one boolean +result for each element of vector mode @var{mode}. The returned mask mode +can be a vector of integers (class @code{MODE_VECTOR_INT}), a vector of +booleans (class @code{MODE_VECTOR_BOOL}) or a scalar integer (class +@code{MODE_INT}). Return an empty @code{opt_machine_mode} if no such +mask mode exists. -The default implementation returns the mode of an integer vector that -is @var{length} bytes long and that contains @var{nunits} elements, -if such a mode exists. +The default implementation returns a @code{MODE_VECTOR_INT} with the +same size and number of elements as @var{mode}, if such a mode exists. @end deftypefn @deftypefn {Target Hook} bool TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE (unsigned @var{ifn}) Index: gcc/targhooks.h =================================================================== --- gcc/targhooks.h 2019-10-23 11:33:01.568510253 +0100 +++ gcc/targhooks.h 2019-10-23 12:13:54.099122100 +0100 @@ -117,7 +117,7 @@ extern void default_autovectorize_vector extern opt_machine_mode default_vectorize_related_mode (machine_mode, scalar_mode, poly_uint64); -extern opt_machine_mode default_get_mask_mode (poly_uint64, poly_uint64); +extern opt_machine_mode default_get_mask_mode (machine_mode); extern bool default_empty_mask_is_expensive (unsigned); extern void *default_init_cost (class loop *); extern unsigned default_add_stmt_cost (void *, int, enum vect_cost_for_stmt, Index: gcc/targhooks.c =================================================================== --- gcc/targhooks.c 2019-10-23 11:33:01.568510253 +0100 +++ gcc/targhooks.c 2019-10-23 12:13:54.099122100 +0100 @@ -1329,21 +1329,9 @@ default_vectorize_related_mode (machine_ /* By default a vector of integers is used as a mask. */ opt_machine_mode -default_get_mask_mode (poly_uint64 nunits, poly_uint64 vector_size) +default_get_mask_mode (machine_mode mode) { - unsigned int elem_size = vector_element_size (vector_size, nunits); - scalar_int_mode elem_mode - = smallest_int_mode_for_size (elem_size * BITS_PER_UNIT); - machine_mode vector_mode; - - gcc_assert (known_eq (elem_size * nunits, vector_size)); - - if (mode_for_vector (elem_mode, nunits).exists (&vector_mode) - && VECTOR_MODE_P (vector_mode) - && targetm.vector_mode_supported_p (vector_mode)) - return vector_mode; - - return opt_machine_mode (); + return related_int_vector_mode (mode); } /* By default consider masked stores to be expensive. */ Index: gcc/optabs-query.c =================================================================== --- gcc/optabs-query.c 2019-10-23 11:33:01.564510281 +0100 +++ gcc/optabs-query.c 2019-10-23 12:13:54.099122100 +0100 @@ -585,8 +585,7 @@ can_vec_mask_load_store_p (machine_mode if (!VECTOR_MODE_P (vmode)) return false; - if ((targetm.vectorize.get_mask_mode - (GET_MODE_NUNITS (vmode), GET_MODE_SIZE (vmode)).exists (&mask_mode)) + if (targetm.vectorize.get_mask_mode (vmode).exists (&mask_mode) && convert_optab_handler (op, vmode, mask_mode) != CODE_FOR_nothing) return true; @@ -600,7 +599,7 @@ can_vec_mask_load_store_p (machine_mode continue; if (mode_for_vector (smode, nunits).exists (&vmode) && VECTOR_MODE_P (vmode) - && targetm.vectorize.get_mask_mode (nunits, cur).exists (&mask_mode) + && targetm.vectorize.get_mask_mode (vmode).exists (&mask_mode) && convert_optab_handler (op, vmode, mask_mode) != CODE_FOR_nothing) return true; } Index: gcc/tree-vect-stmts.c =================================================================== --- gcc/tree-vect-stmts.c 2019-10-23 12:10:58.116366179 +0100 +++ gcc/tree-vect-stmts.c 2019-10-23 12:13:54.103122072 +0100 @@ -1948,9 +1948,8 @@ check_load_store_masking (loop_vec_info } machine_mode mask_mode; - if (!(targetm.vectorize.get_mask_mode - (GET_MODE_NUNITS (vecmode), - GET_MODE_SIZE (vecmode)).exists (&mask_mode)) + if (!VECTOR_MODE_P (vecmode) + || !targetm.vectorize.get_mask_mode (vecmode).exists (&mask_mode) || !can_vec_mask_load_store_p (vecmode, mask_mode, is_load)) { if (dump_enabled_p ()) Index: gcc/tree.c =================================================================== --- gcc/tree.c 2019-10-23 12:10:58.116366179 +0100 +++ gcc/tree.c 2019-10-23 12:13:54.103122072 +0100 @@ -11134,15 +11134,15 @@ build_truth_vector_type_for_mode (poly_u static tree build_truth_vector_type_for (tree vectype) { + machine_mode vector_mode = TYPE_MODE (vectype); poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); - poly_uint64 vector_size = tree_to_poly_uint64 (TYPE_SIZE_UNIT (vectype)); machine_mode mask_mode; - if (targetm.vectorize.get_mask_mode (nunits, - vector_size).exists (&mask_mode)) + if (VECTOR_MODE_P (vector_mode) + && targetm.vectorize.get_mask_mode (vector_mode).exists (&mask_mode)) return build_truth_vector_type_for_mode (nunits, mask_mode); - poly_uint64 vsize = vector_size * BITS_PER_UNIT; + poly_uint64 vsize = tree_to_poly_uint64 (TYPE_SIZE (vectype)); unsigned HOST_WIDE_INT esize = vector_element_size (vsize, nunits); tree bool_type = build_nonstandard_boolean_type (esize); Index: gcc/config/aarch64/aarch64.c =================================================================== --- gcc/config/aarch64/aarch64.c 2019-10-23 12:01:36.964336643 +0100 +++ gcc/config/aarch64/aarch64.c 2019-10-23 12:13:54.087122185 +0100 @@ -1721,17 +1721,13 @@ aarch64_sve_pred_mode (unsigned int elem /* Implement TARGET_VECTORIZE_GET_MASK_MODE. */ static opt_machine_mode -aarch64_get_mask_mode (poly_uint64 nunits, poly_uint64 nbytes) +aarch64_get_mask_mode (machine_mode mode) { - if (TARGET_SVE && known_eq (nbytes, BYTES_PER_SVE_VECTOR)) - { - unsigned int elem_nbytes = vector_element_size (nbytes, nunits); - machine_mode pred_mode; - if (aarch64_sve_pred_mode (elem_nbytes).exists (&pred_mode)) - return pred_mode; - } + unsigned int vec_flags = aarch64_classify_vector_mode (mode); + if (vec_flags & VEC_SVE_DATA) + return aarch64_sve_pred_mode (GET_MODE_UNIT_SIZE (mode)); - return default_get_mask_mode (nunits, nbytes); + return default_get_mask_mode (mode); } /* Return the SVE vector mode that has NUNITS elements of mode INNER_MODE. */ @@ -18598,9 +18594,7 @@ aarch64_expand_sve_vec_cmp_float (rtx ta aarch64_expand_sve_vcond (machine_mode data_mode, machine_mode cmp_mode, rtx *ops) { - machine_mode pred_mode - = aarch64_get_mask_mode (GET_MODE_NUNITS (cmp_mode), - GET_MODE_SIZE (cmp_mode)).require (); + machine_mode pred_mode = aarch64_get_mask_mode (cmp_mode).require (); rtx pred = gen_reg_rtx (pred_mode); if (FLOAT_MODE_P (cmp_mode)) { Index: gcc/config/gcn/gcn.c =================================================================== --- gcc/config/gcn/gcn.c 2019-09-30 17:20:00.831015023 +0100 +++ gcc/config/gcn/gcn.c 2019-10-23 12:13:54.091122156 +0100 @@ -3786,8 +3786,7 @@ gcn_expand_builtin (tree exp, rtx target a vector. */ opt_machine_mode -gcn_vectorize_get_mask_mode (poly_uint64 ARG_UNUSED (nunits), - poly_uint64 ARG_UNUSED (length)) +gcn_vectorize_get_mask_mode (nachine_mode) { /* GCN uses a DImode bit-mask. */ return DImode; Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c 2019-10-21 07:40:23.826383171 +0100 +++ gcc/config/i386/i386.c 2019-10-23 12:13:54.095122128 +0100 @@ -21421,8 +21421,10 @@ ix86_autovectorize_vector_sizes (vector_ /* Implemenation of targetm.vectorize.get_mask_mode. */ static opt_machine_mode -ix86_get_mask_mode (poly_uint64 nunits, poly_uint64 vector_size) +ix86_get_mask_mode (machine_mode data_mode) { + unsigned vector_size = GET_MODE_SIZE (data_mode); + unsigned nunits = GET_MODE_NUNITS (data_mode); unsigned elem_size = vector_size / nunits; /* Scalar mask case. */