https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69888

--- Comment #2 from Uroš Bizjak <ubizjak at gmail dot com> ---
(In reply to Jakub Jelinek from comment #1)

> Untested fix.
Looks OK, but please introduce a temporary variable, something like:

--cut here--
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c                    
index a1c87ab..6457293 100644                                                   
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -26152,20 +26152,23 @@ decide_alg (HOST_WIDE_INT count, HOST_WIDE_INT
expected_size,
          || !alg_usable_p (algs->unknown_size, memset, have_as)))
     {
       enum stringop_alg alg;
+      HOST_WIDE_INT new_size;

-      /* If there aren't any usable algorithms, then recursing on
-         smaller sizes isn't going to find anything.  Just return the
-         simple byte-at-a-time copy loop.  */
-      if (!any_alg_usable_p)
+      if (max <= 0)
+       max = 4096;
+      /* If there aren't any usable algorithms or if recursing with the
+        same arguments as before, then recursing on smaller sizes or
+        same size isn't going to find anything.  Just return the simple
+        byte-at-a-time copy loop.  */
+      new_size = max / 2;
+      if (!any_alg_usable_p || new_size == orig_expected_size)
         {
           /* Pick something reasonable.  */
           if (TARGET_INLINE_STRINGOPS_DYNAMICALLY)
             *dynamic_check = 128;
           return loop_1_byte;
         }
-      if (max <= 0)
-       max = 4096;
-      alg = decide_alg (count, max / 2, min_size, max_size, memset,
+      alg = decide_alg (count, new_size, min_size, max_size, memset,
                        zero_memset, have_as, dynamic_check, noalign);
       gcc_assert (*dynamic_check == -1);
       if (TARGET_INLINE_STRINGOPS_DYNAMICALLY)
--cut here--

Reply via email to