From: Richard Biener Date: Thu, 26 Jun 2025 09:38:47 +0000 (+0200) Subject: Fixup vector epilog analysis skipping when not using partial vectors X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f359b9150c282c69704d8d2a6c8e071c90506538;p=thirdparty%2Fgcc.git Fixup vector epilog analysis skipping when not using partial vectors The following avoids re-analyzing the loop as epilogue when not using partial vectors and the mode is the same as the autodetected vector mode and that has a too high VF for a non-predicated loop. This situation occurs almost always on x86 and saves us one re-analysis unless --param vect-partial-vector-usage is non-default. * tree-vectorizer.h (vect_chooses_same_modes_p): New overload. * tree-vect-stmts.cc (vect_chooses_same_modes_p): Likewise. * tree-vect-loop.cc (vect_analyze_loop): Prune epilogue analysis further when not using partial vectors. --- diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 18404f01c1e..575987e4bf0 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -3494,13 +3494,8 @@ vect_analyze_loop_1 (class loop *loop, vec_info_shared *shared, mode_i += 1; } if (mode_i + 1 < vector_modes.length () - && VECTOR_MODE_P (autodetected_vector_mode) - && (related_vector_mode (vector_modes[mode_i + 1], - GET_MODE_INNER (autodetected_vector_mode)) - == autodetected_vector_mode) - && (related_vector_mode (autodetected_vector_mode, - GET_MODE_INNER (vector_modes[mode_i + 1])) - == vector_modes[mode_i + 1])) + && vect_chooses_same_modes_p (autodetected_vector_mode, + vector_modes[mode_i + 1])) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, @@ -3729,6 +3724,22 @@ vect_analyze_loop (class loop *loop, gimple *loop_vectorized_call, break; continue; } + /* We would need an exhaustive search to find all modes we + skipped but that would lead to the same result as the + analysis it was skipped for and where we'd could check + cached_vf_per_mode against. + Check for the autodetected mode, which is the common + situation on x86 which does not perform cost comparison. */ + if (!supports_partial_vectors + && maybe_ge (cached_vf_per_mode[0], first_vinfo_vf) + && vect_chooses_same_modes_p (autodetected_vector_mode, + vector_modes[mode_i])) + { + mode_i++; + if (mode_i == vector_modes.length ()) + break; + continue; + } if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 1adc23c403f..69f5f6758a1 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -13947,6 +13947,23 @@ vect_chooses_same_modes_p (vec_info *vinfo, machine_mode vector_mode) return true; } +/* Return true if replacing VECTOR_MODE with ALT_VECTOR_MODE would not + change the chosen vector modes for analysis of a loop. */ + +bool +vect_chooses_same_modes_p (machine_mode vector_mode, + machine_mode alt_vector_mode) +{ + return (VECTOR_MODE_P (vector_mode) + && VECTOR_MODE_P (alt_vector_mode) + && (related_vector_mode (vector_mode, + GET_MODE_INNER (alt_vector_mode)) + == alt_vector_mode) + && (related_vector_mode (alt_vector_mode, + GET_MODE_INNER (vector_mode)) + == vector_mode)); +} + /* Function vect_is_simple_use. Input: diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 0444adf5322..66a29648fb4 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -2411,6 +2411,7 @@ extern tree get_mask_type_for_scalar_type (vec_info *, tree, unsigned int = 0); extern tree get_mask_type_for_scalar_type (vec_info *, tree, slp_tree); extern tree get_same_sized_vectype (tree, tree); extern bool vect_chooses_same_modes_p (vec_info *, machine_mode); +extern bool vect_chooses_same_modes_p (machine_mode, machine_mode); extern bool vect_get_loop_mask_type (loop_vec_info); extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *, stmt_vec_info * = NULL, gimple ** = NULL);