--- Comment #30 from Zack Weinberg <zackw at panix dot com> ---
It's been a very long time and I don't know exactly what changed, but GCC 7.3
generates essentially the same code for both of the functions in the "C test
case" and I would not describe that code as "bad".
I can still make it duplicate the entire body of the loop by relatively small
tweaks, though. For instance,
int has_bad_chars(char *str, __SIZE_TYPE__ len)
for (char *c = str; c < str + len; c++)
unsigned char x = (unsigned char)(*c);
if (x <= 0x1f || x == 0x5c || x == 0x7f)
generates significantly worse code (doubling cache footprint for no gain in
branch predictability or any other metric) with -O2 than -Os.
Also, the code generated for the body of the loop (with both the original test
case and the above) is more complicated than it needs to be, but perhaps that
should be a new bug report.