From b161f2c927bb7fb70dc0c6d4e9ab22cdba29db6d Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 18 Sep 2017 15:39:21 +0000 Subject: [PATCH] Include phis in SLP unrolling calculation Without this we'd pick an unrolling factor based purely on longs, ignoring the ints. It's posssible that vect_get_smallest_scalar_type should also handle shifts, but I think we'd still want this as a belt-and-braces fix. 2017-09-18 Richard Sandiford gcc/ * tree-vect-slp.c (vect_record_max_nunits): New function, split out from... (vect_build_slp_tree_1): ...here. (vect_build_slp_tree_2): Call it for phis too. gcc/testsuite/ * gcc.dg/vect/slp-multitypes-13.c: New test. From-SVN: r252933 --- gcc/ChangeLog | 7 ++ gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gcc.dg/vect/slp-multitypes-13.c | 11 +++ gcc/tree-vect-slp.c | 78 ++++++++++++------- 4 files changed, 73 insertions(+), 27 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/slp-multitypes-13.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 70b73509c4e..130793eaf5a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-09-18 Richard Sandiford + + * tree-vect-slp.c (vect_record_max_nunits): New function, + split out from... + (vect_build_slp_tree_1): ...here. + (vect_build_slp_tree_2): Call it for phis too. + 2017-09-18 Richard Sandiford * tree-vect-stmts.c (vectorizable_mask_load_store): Pass mask_vectype diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a4662844f84..c0de42aa5a6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-09-18 Richard Sandiford + + * gcc.dg/vect/slp-multitypes-13.c: New test. + 2017-09-18 Richard Sandiford * gfortran.dg/vect/mask-store-1.f90: New test. diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-13.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-13.c new file mode 100644 index 00000000000..bbbbb2c64b4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-13.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ + +void +f (long *x, int n) +{ + for (int i = 0; i < n; i++) + { + x[i * 2] = 1L << i; + x[i * 2 + 1] = 1L << i; + } +} diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 32174fe6bb0..0168f8bdeb8 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -480,6 +480,48 @@ again: return 0; } +/* A subroutine of vect_build_slp_tree for checking VECTYPE, which is the + caller's attempt to find the vector type in STMT with the narrowest + element type. Return true if VECTYPE is nonnull and if it is valid + for VINFO. When returning true, update MAX_NUNITS to reflect the + number of units in VECTYPE. VINFO, GORUP_SIZE and MAX_NUNITS are + as for vect_build_slp_tree. */ + +static bool +vect_record_max_nunits (vec_info *vinfo, gimple *stmt, unsigned int group_size, + tree vectype, unsigned int *max_nunits) +{ + if (!vectype) + { + if (dump_enabled_p ()) + { + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "Build SLP failed: unsupported data-type in "); + dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); + } + /* Fatal mismatch. */ + return false; + } + + /* If populating the vector type requires unrolling then fail + before adjusting *max_nunits for basic-block vectorization. */ + if (is_a (vinfo) + && TYPE_VECTOR_SUBPARTS (vectype) > group_size) + { + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "Build SLP failed: unrolling required " + "in basic block SLP\n"); + /* Fatal mismatch. */ + return false; + } + + /* In case of multiple types we need to detect the smallest type. */ + if (*max_nunits < TYPE_VECTOR_SUBPARTS (vectype)) + *max_nunits = TYPE_VECTOR_SUBPARTS (vectype); + + return true; +} /* Verify if the scalar stmts STMTS are isomorphic, require data permutation or are of unsupported types of operation. Return @@ -560,38 +602,14 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap, scalar_type = vect_get_smallest_scalar_type (stmt, &dummy, &dummy); vectype = get_vectype_for_scalar_type (scalar_type); - if (!vectype) - { - if (dump_enabled_p ()) - { - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Build SLP failed: unsupported data-type "); - dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, - scalar_type); - dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); - } + if (!vect_record_max_nunits (vinfo, stmt, group_size, vectype, + max_nunits)) + { /* Fatal mismatch. */ matches[0] = false; return false; } - /* If populating the vector type requires unrolling then fail - before adjusting *max_nunits for basic-block vectorization. */ - if (is_a (vinfo) - && TYPE_VECTOR_SUBPARTS (vectype) > group_size) - { - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Build SLP failed: unrolling required " - "in basic block SLP\n"); - /* Fatal mismatch. */ - matches[0] = false; - return false; - } - - /* In case of multiple types we need to detect the smallest type. */ - if (*max_nunits < TYPE_VECTOR_SUBPARTS (vectype)) - *max_nunits = TYPE_VECTOR_SUBPARTS (vectype); - if (gcall *call_stmt = dyn_cast (stmt)) { rhs_code = CALL_EXPR; @@ -1018,6 +1036,12 @@ vect_build_slp_tree_2 (vec_info *vinfo, the recursion. */ if (gimple_code (stmt) == GIMPLE_PHI) { + tree scalar_type = TREE_TYPE (PHI_RESULT (stmt)); + tree vectype = get_vectype_for_scalar_type (scalar_type); + if (!vect_record_max_nunits (vinfo, stmt, group_size, vectype, + max_nunits)) + return NULL; + vect_def_type def_type = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (stmt)); /* Induction from different IVs is not supported. */ if (def_type == vect_induction_def) -- 2.30.2