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-10-24 Richard Sandiford <[email protected]>
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.
Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c 2019-10-25 13:27:26.205687511 +0100
+++ gcc/tree-vect-stmts.c 2019-10-25 13:27:32.877640367 +0100
@@ -11973,7 +11973,12 @@ vect_get_vector_types_for_stmt (stmt_vec
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));
@@ -12005,7 +12010,7 @@ vect_get_vector_types_for_stmt (stmt_vec
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,
@@ -12022,42 +12027,38 @@ vect_get_vector_types_for_stmt (stmt_vec
/* 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");