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. --- gcc/config/i386/i386.c.jj 2016-03-02 14:08:00.000000000 +0100 +++ gcc/config/i386/i386.c 2016-03-03 17:48:18.587450348 +0100 @@ -26170,11 +26170,15 @@ decide_alg (HOST_WIDE_INT count, HOST_WI } 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 128 above because we avoided + infinite recursion. */ + gcc_assert (*dynamic_check == -1 || *dynamic_check == 128); + *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) --- gcc/testsuite/gcc.target/i386/pr70062.c.jj 2016-03-03 17:54:13.167642050 +0100 +++ gcc/testsuite/gcc.target/i386/pr70062.c 2016-03-03 17:54:58.753023808 +0100 @@ -0,0 +1,11 @@ +/* PR target/70062 */ +/* { dg-options "-minline-all-stringops -minline-stringops-dynamically -mmemcpy-strategy=libcall:-1:noalign -Wno-psabi" } */ +/* { dg-additional-options "-mtune=k6-2" { target ia32 } } */ + +typedef int V __attribute__ ((vector_size (32))); + +V +foo (V x) +{ + return (V) { x[0] }; +} Jakub