]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fixup vector epilog analysis skipping when not using partial vectors
authorRichard Biener <rguenther@suse.de>
Thu, 26 Jun 2025 09:38:47 +0000 (11:38 +0200)
committerRichard Biener <rguenther@suse.de>
Fri, 27 Jun 2025 09:06:57 +0000 (11:06 +0200)
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.

gcc/tree-vect-loop.cc
gcc/tree-vect-stmts.cc
gcc/tree-vectorizer.h

index 18404f01c1eaff028ec2a8eee730230c29680515..575987e4bf0142b3d9b118afea0481fd193cf6fd 100644 (file)
@@ -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,
index 1adc23c403fe8f135aac72b830ab8d84a5e67966..69f5f6758a15c265c85c1621d143771d8701ab12 100644 (file)
@@ -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:
index 0444adf5322da8b19e587f1e47e2d3aeeffa68ca..66a29648fb40dfdd2f2b237e5c83107b8cba895a 100644 (file)
@@ -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);