On Thu, Mar 3, 2016 at 9:16 PM, Jakub Jelinek <ja...@redhat.com> wrote: > Hi! > > Before my recent decide_alg change, *dynamic_check == -1 was indeed > guaranteed, because any_alg_usable_p doesn't depend on the arguments of > decide_alg that might change during recursive call, so we'd only recurse if > it wouldn't set *dynamic_check. But, if we give up because we'd otherwise > recurse infinitely, we can set *dynamic_check to 128. > > Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for > trunk? > > 2016-03-03 Jakub Jelinek <ja...@redhat.com> > > PR target/70062 > * config/i386/i386.c (decide_alg): If > TARGET_INLINE_STRINGOPS_DYNAMICALLY, allow *dynamic_check to be also > 128 from the recursive call. > > * gcc.target/i386/pr70062.c: New test.
I don't like the fact that *dynamic_check is set to max (which is 0 with your testcase) when recursion avoidance code already set it to "something reasonable", together with loop_1_byte alg. What do you think about attached (lightly tested) patch? Uros.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 8a026ae..ded9951 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -26170,11 +26170,22 @@ decide_alg (HOST_WIDE_INT count, HOST_WIDE_INT expected_size, } alg = decide_alg (count, new_expected_size, min_size, max_size, memset, zero_memset, have_as, dynamic_check, noalign); - gcc_assert (*dynamic_check == -1); + if (TARGET_INLINE_STRINGOPS_DYNAMICALLY) - *dynamic_check = max; + { + /* *dynamic_check could be set to 128 above because we avoided + infinite recursion. */ + if (*dynamic_check == 128) + gcc_assert (alg == loop_1_byte); + else + { + gcc_assert (*dynamic_check == -1); + *dynamic_check = max; + } + } else - gcc_assert (alg != libcall); + gcc_assert (alg != libcall && *dynamic_check == -1); + return alg; } return (alg_usable_p (algs->unknown_size, memset, have_as)