This patch makes vectorizable_call handle variable-length vectors. The only substantial change is to use build_index_vector for IFN_GOMP_SIMD_LANE; this makes no functional difference for fixed-length vectors.
2017-10-23 Richard Sandiford <richard.sandif...@linaro.org> Alan Hayward <alan.hayw...@arm.com> David Sherwood <david.sherw...@arm.com> gcc/ * tree-vect-stmts.c (vectorizable_call): Treat the number of vectors as polynomial. Use build_index_vector for IFN_GOMP_SIMD_LANE. Index: gcc/tree-vect-stmts.c =================================================================== --- gcc/tree-vect-stmts.c 2017-10-23 17:22:38.938582823 +0100 +++ gcc/tree-vect-stmts.c 2017-10-23 17:22:39.943478586 +0100 @@ -2637,8 +2637,8 @@ vectorizable_call (gimple *gs, gimple_st tree vec_oprnd0 = NULL_TREE, vec_oprnd1 = NULL_TREE; stmt_vec_info stmt_info = vinfo_for_stmt (gs), prev_stmt_info; tree vectype_out, vectype_in; - int nunits_in; - int nunits_out; + poly_uint64 nunits_in; + poly_uint64 nunits_out; loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info); vec_info *vinfo = stmt_info->vinfo; @@ -2758,11 +2758,11 @@ vectorizable_call (gimple *gs, gimple_st /* FORNOW */ nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in); nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out); - if (nunits_in == nunits_out / 2) + if (must_eq (nunits_in * 2, nunits_out)) modifier = NARROW; - else if (nunits_out == nunits_in) + else if (must_eq (nunits_out, nunits_in)) modifier = NONE; - else if (nunits_out == nunits_in / 2) + else if (must_eq (nunits_out * 2, nunits_in)) modifier = WIDEN; else return false; @@ -2961,11 +2961,7 @@ vectorizable_call (gimple *gs, gimple_st if (gimple_call_internal_p (stmt) && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE) { - auto_vec<tree, 32> v (nunits_out); - for (int k = 0; k < nunits_out; ++k) - v.quick_push (build_int_cst (unsigned_type_node, - j * nunits_out + k)); - tree cst = build_vector (vectype_out, v); + tree cst = build_index_vector (vectype_out, j * nunits_out, 1); tree new_var = vect_get_new_ssa_name (vectype_out, vect_simple_var, "cst_"); gimple *init_stmt = gimple_build_assign (new_var, cst);