This patch splits the mask argument checking out of vectorizable_mask_load_store, so that a later patch can use it in both vectorizable_load and vectorizable_store. It also adds dump messages for false returns. This is mostly useful for the TYPE_VECTOR_SUBPARTS check, which can fail if pattern recognition didn't convert the mask properly.
Richard 2017-11-17 Richard Sandiford <richard.sandif...@linaro.org> gcc/ * tree-vect-stmts.c (vect_check_load_store_mask): New function, split out from... (vectorizable_mask_load_store): ...here. Index: gcc/tree-vect-stmts.c =================================================================== --- gcc/tree-vect-stmts.c 2017-11-17 09:06:46.238323981 +0000 +++ gcc/tree-vect-stmts.c 2017-11-17 09:06:49.784303349 +0000 @@ -2023,6 +2023,74 @@ get_load_store_type (gimple *stmt, tree return true; } +/* Return true if boolean argument MASK is suitable for vectorizing + conditional load or store STMT. When returning true, store the + type of the vectorized mask in *MASK_VECTYPE_OUT. */ + +static bool +vect_check_load_store_mask (gimple *stmt, tree mask, tree *mask_vectype_out) +{ + if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (mask))) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "mask argument is not a boolean.\n"); + return false; + } + + if (TREE_CODE (mask) != SSA_NAME) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "mask argument is not an SSA name.\n"); + return false; + } + + stmt_vec_info stmt_info = vinfo_for_stmt (stmt); + gimple *def_stmt; + enum vect_def_type dt; + tree mask_vectype; + if (!vect_is_simple_use (mask, stmt_info->vinfo, &def_stmt, &dt, + &mask_vectype)) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "mask use not simple.\n"); + return false; + } + + tree vectype = STMT_VINFO_VECTYPE (stmt_info); + if (!mask_vectype) + mask_vectype = get_mask_type_for_scalar_type (TREE_TYPE (vectype)); + + if (!mask_vectype || !VECTOR_BOOLEAN_TYPE_P (mask_vectype)) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "could not find an appropriate vector mask type.\n"); + return false; + } + + if (may_ne (TYPE_VECTOR_SUBPARTS (mask_vectype), + TYPE_VECTOR_SUBPARTS (vectype))) + { + if (dump_enabled_p ()) + { + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "vector mask type "); + dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, mask_vectype); + dump_printf (MSG_MISSED_OPTIMIZATION, + " does not match vector data type "); + dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, vectype); + dump_printf (MSG_MISSED_OPTIMIZATION, ".\n"); + } + return false; + } + + *mask_vectype_out = mask_vectype; + return true; +} + /* Function vectorizable_mask_load_store. Check if STMT performs a conditional load or store that can be vectorized. @@ -2065,11 +2133,6 @@ vectorizable_mask_load_store (gimple *st ncopies = vect_get_num_copies (loop_vinfo, vectype); gcc_assert (ncopies >= 1); - mask = gimple_call_arg (stmt, 2); - - if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (mask))) - return false; - /* FORNOW. This restriction should be relaxed. */ if (nested_in_vect_loop && ncopies > 1) { @@ -2089,21 +2152,11 @@ vectorizable_mask_load_store (gimple *st if (!STMT_VINFO_DATA_REF (stmt_info)) return false; - elem_type = TREE_TYPE (vectype); - - if (TREE_CODE (mask) != SSA_NAME) - return false; - - if (!vect_is_simple_use (mask, loop_vinfo, &def_stmt, &dt, &mask_vectype)) + mask = gimple_call_arg (stmt, 2); + if (!vect_check_load_store_mask (stmt, mask, &mask_vectype)) return false; - if (!mask_vectype) - mask_vectype = get_mask_type_for_scalar_type (TREE_TYPE (vectype)); - - if (!mask_vectype || !VECTOR_BOOLEAN_TYPE_P (mask_vectype) - || may_ne (TYPE_VECTOR_SUBPARTS (mask_vectype), - TYPE_VECTOR_SUBPARTS (vectype))) - return false; + elem_type = TREE_TYPE (vectype); if (gimple_call_internal_fn (stmt) == IFN_MASK_STORE) {