]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[x86] override vector_costs::better_epilogue_loop_than_p
authorRichard Biener <rguenther@suse.de>
Tue, 28 Apr 2026 12:55:04 +0000 (14:55 +0200)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 30 Apr 2026 06:12:46 +0000 (08:12 +0200)
The following resolves the gcc.target/i386/vect-epilogues-3.c failure
when --param ix86-vect-compare-costs=1 is specified.  When the target
requests multiple epilogues to be used and the new candidate is the
epilogue of choice of the currently prevailing epilogue keep that.

But avoid doing so if the new candidate uses a vectorization factor
of one which should be an optimal vector epilog.  This avoids
regressing gcc.dg/vect/costmodel/x86_64/costmodel-pr122573.c

* config/i386/i386.cc (ix86_vector_costs::better_epilogue_loop_than_p):
New.  If the other loop suggests this as epilog prefer other.

gcc/config/i386/i386.cc

index b92338bc6dd091d54369939b97ed82425a4f4be0..c11da783c8cfb22c044e7f2555775e22cfdc3a6b 100644 (file)
@@ -26129,6 +26129,8 @@ public:
                              vect_cost_model_location where) override;
   void finish_cost (const vector_costs *) override;
   bool better_main_loop_than_p (const vector_costs *) const override;
+  bool better_epilogue_loop_than_p (const vector_costs *other,
+                                   loop_vec_info main_loop) const;
 
 private:
 
@@ -27010,6 +27012,25 @@ ix86_vector_costs::better_main_loop_than_p (const vector_costs *other) const
   return vector_costs::better_main_loop_than_p (other);
 }
 
+/* Return true if THIS should be preferred over OTHER as epilog vector
+   loop when vectorizing MAIN_LOOP.  */
+
+bool
+ix86_vector_costs::better_epilogue_loop_than_p (const vector_costs *other,
+                                               loop_vec_info main_loop) const
+{
+  loop_vec_info this_loop_info = as_a <loop_vec_info> (this->vinfo ());
+  /* The x86 target allows for multiple vector epilogues, if THIS is
+     the suggested epilog mode of OTHER then keep the latter unless
+     THIS has a VF of one which means no further epilog needed.  */
+  int tem;
+  if (known_gt (LOOP_VINFO_VECT_FACTOR (this_loop_info), 1U)
+      && (GET_MODE_SIZE (other->suggested_epilogue_mode (tem))
+         == GET_MODE_SIZE (this_loop_info->vector_mode)))
+    return false;
+  return vector_costs::better_epilogue_loop_than_p (other, main_loop);
+}
+
 /* Validate target specific memory model bits in VAL. */
 
 static unsigned HOST_WIDE_INT