This patch makes two-operation SLP handle but reject variable-length vectors. Adding support for this is a post-GCC8 thing.
2017-10-23 Richard Sandiford <richard.sandif...@linaro.org> Alan Hayward <alan.hayw...@arm.com> David Sherwood <david.sherw...@arm.com> gcc/ * tree-vect-slp.c (vect_build_slp_tree_1): Handle polynomial numbers of units. (vect_schedule_slp_instance): Likewise. Index: gcc/tree-vect-slp.c =================================================================== --- gcc/tree-vect-slp.c 2017-10-23 17:22:42.827179461 +0100 +++ gcc/tree-vect-slp.c 2017-10-23 17:22:43.865071801 +0100 @@ -903,10 +903,19 @@ vect_build_slp_tree_1 (vec_info *vinfo, /* If we allowed a two-operation SLP node verify the target can cope with the permute we are going to use. */ + poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); if (alt_stmt_code != ERROR_MARK && TREE_CODE_CLASS (alt_stmt_code) != tcc_reference) { - unsigned int count = TYPE_VECTOR_SUBPARTS (vectype); + unsigned HOST_WIDE_INT count; + if (!nunits.is_constant (&count)) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "Build SLP failed: different operations " + "not allowed with variable-length SLP.\n"); + return false; + } auto_vec_perm_indices sel (count); for (i = 0; i < count; ++i) { @@ -3796,6 +3805,7 @@ vect_schedule_slp_instance (slp_tree nod /* VECTYPE is the type of the destination. */ vectype = STMT_VINFO_VECTYPE (stmt_info); + poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); group_size = SLP_INSTANCE_GROUP_SIZE (instance); if (!SLP_TREE_VEC_STMTS (node).exists ()) @@ -3858,13 +3868,16 @@ vect_schedule_slp_instance (slp_tree nod unsigned k = 0, l; for (j = 0; j < v0.length (); ++j) { - unsigned int nunits = TYPE_VECTOR_SUBPARTS (vectype); - auto_vec<tree, 32> melts (nunits); - for (l = 0; l < nunits; ++l) + /* Enforced by vect_build_slp_tree, which rejects variable-length + vectors for SLP_TREE_TWO_OPERATORS. */ + unsigned int const_nunits = nunits.to_constant (); + auto_vec<tree, 32> melts (const_nunits); + for (l = 0; l < const_nunits; ++l) { if (k >= group_size) k = 0; - tree t = build_int_cst (meltype, mask[k++] * nunits + l); + tree t = build_int_cst (meltype, + mask[k++] * const_nunits + l); melts.quick_push (t); } tmask = build_vector (mvectype, melts);