From 05101d1b575a57ca26e4275e971da85a0dd1d52a Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 14 Nov 2019 15:16:40 +0000 Subject: [PATCH] Allow mixed vector sizes within a single vectorised stmt Although a previous patch allowed mixed vector sizes within a vector region, we generally still required equal vector sizes within a vector stmt. Specifically, vect_get_vector_types_for_stmt computes two vector types: the vector type corresponding to STMT_VINFO_VECTYPE and the vector type that determines the minimum vectorisation factor for the stmt ("nunits_vectype"). It then required these two types to be the same size. There doesn't seem to be any need for that restriction though. AFAICT, all vectorizable_* functions either do their own compatibility checks or don't need to do them (because gimple guarantees that the scalar types are compatible). It should always be the case that nunits_vectype has at least as many elements as the other vectype, but that's something we can assert for. I couldn't resist a couple of other tweaks while there: - there's no need to compute nunits_vectype if its element type is the same as STMT_VINFO_VECTYPE's. - it's useful to distinguish the nunits_vectype from the main vectype in dump messages - when reusing the existing STMT_VINFO_VECTYPE, it's useful to say so in the dump, and say what the type is 2019-11-14 Richard Sandiford gcc/ * tree-vect-stmts.c (vect_get_vector_types_for_stmt): Don't require vectype and nunits_vectype to have the same size; instead assert that nunits_vectype has at least as many elements as vectype. Don't compute a separate nunits_vectype if the scalar type is obviously the same as vectype's. Tweak dump messages. From-SVN: r278244 --- gcc/ChangeLog | 9 +++++++++ gcc/tree-vect-stmts.c | 55 ++++++++++++++++++++++++++------------------------- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7515ee1..6bb0a80 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2019-11-14 Richard Sandiford + * tree-vect-stmts.c (vect_get_vector_types_for_stmt): Don't + require vectype and nunits_vectype to have the same size; + instead assert that nunits_vectype has at least as many + elements as vectype. Don't compute a separate nunits_vectype + if the scalar type is obviously the same as vectype's. + Tweak dump messages. + +2019-11-14 Richard Sandiford + * config/aarch64/aarch64.c (aarch64_vectorize_related_mode): New function. (aarch64_autovectorize_vector_modes): Also add V4HImode and V2SImode. diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index e1fa075..5f30d1e 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -12018,7 +12018,12 @@ vect_get_vector_types_for_stmt (stmt_vec_info stmt_info, tree vectype; tree scalar_type = NULL_TREE; if (STMT_VINFO_VECTYPE (stmt_info)) - *stmt_vectype_out = vectype = STMT_VINFO_VECTYPE (stmt_info); + { + *stmt_vectype_out = vectype = STMT_VINFO_VECTYPE (stmt_info); + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "precomputed vectype: %T\n", vectype); + } else { gcc_assert (!STMT_VINFO_DATA_REF (stmt_info)); @@ -12050,7 +12055,7 @@ vect_get_vector_types_for_stmt (stmt_vec_info stmt_info, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "get vectype for scalar type: %T\n", scalar_type); + "get vectype for scalar type: %T\n", scalar_type); vectype = get_vectype_for_scalar_type (vinfo, scalar_type); if (!vectype) return opt_result::failure_at (stmt, @@ -12067,42 +12072,38 @@ vect_get_vector_types_for_stmt (stmt_vec_info stmt_info, /* Don't try to compute scalar types if the stmt produces a boolean vector; use the existing vector type instead. */ - tree nunits_vectype; - if (VECTOR_BOOLEAN_TYPE_P (vectype)) - nunits_vectype = vectype; - else + tree nunits_vectype = vectype; + if (!VECTOR_BOOLEAN_TYPE_P (vectype) + && *stmt_vectype_out != boolean_type_node) { /* The number of units is set according to the smallest scalar type (or the largest vector size, but we only support one vector size per vectorization). */ - if (*stmt_vectype_out != boolean_type_node) + HOST_WIDE_INT dummy; + scalar_type = vect_get_smallest_scalar_type (stmt_info, &dummy, &dummy); + if (scalar_type != TREE_TYPE (vectype)) { - HOST_WIDE_INT dummy; - scalar_type = vect_get_smallest_scalar_type (stmt_info, - &dummy, &dummy); + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "get vectype for smallest scalar type: %T\n", + scalar_type); + nunits_vectype = get_vectype_for_scalar_type (vinfo, scalar_type); + if (!nunits_vectype) + return opt_result::failure_at + (stmt, "not vectorized: unsupported data-type %T\n", + scalar_type); + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, "nunits vectype: %T\n", + nunits_vectype); } - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "get vectype for scalar type: %T\n", scalar_type); - nunits_vectype = get_vectype_for_scalar_type (vinfo, scalar_type); } - if (!nunits_vectype) - return opt_result::failure_at (stmt, - "not vectorized: unsupported data-type %T\n", - scalar_type); - if (maybe_ne (GET_MODE_SIZE (TYPE_MODE (vectype)), - GET_MODE_SIZE (TYPE_MODE (nunits_vectype)))) - return opt_result::failure_at (stmt, - "not vectorized: different sized vector " - "types in statement, %T and %T\n", - vectype, nunits_vectype); + gcc_assert (*stmt_vectype_out == boolean_type_node + || multiple_p (TYPE_VECTOR_SUBPARTS (nunits_vectype), + TYPE_VECTOR_SUBPARTS (*stmt_vectype_out))); if (dump_enabled_p ()) { - dump_printf_loc (MSG_NOTE, vect_location, "vectype: %T\n", - nunits_vectype); - dump_printf_loc (MSG_NOTE, vect_location, "nunits = "); dump_dec (MSG_NOTE, TYPE_VECTOR_SUBPARTS (nunits_vectype)); dump_printf (MSG_NOTE, "\n"); -- 2.7.4