https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91026
Peter Cordes <peter at cordes dot ca> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |peter at cordes dot ca
--- Comment #3 from Peter Cordes <peter at cordes dot ca> ---
(In reply to Martin Liška from comment #2)
> Switch conversion bails out because it knowns that a jump table (or a bit
> test can) be used for this snippet. Then we prefer to use a jump table then
> a bit test. With -fno-jump-tables we generate the same code.
> That said, I confirm it's a small limitation.
This regression appeared in GCC9 for this test-case, and is present in GCC9.1
on Godbolt: https://godbolt.org/z/fDjTxN
bool is_vowel(char c) {
switch (c) {
case 'a': case 'e': case 'i': case 'o': case 'u': case 'y':
return 1;
default:
return 0;
}
}
But simplifying it
case 'a': case 'e': case 'i':
to those 3 cases gets gcc9 and trunk to use an immediate bitmap.
With gcc8 and earlier, the x86-64 asm for the 2 versions is identical except
for the immediate used with TEST EAX, imm32.
----
(And BTW, there's a missed optimization here of using mask & (1<<n) instead
of (mask>>n) & 1. Or better, looking for that conversion in user source code /
logic because people often write tests that way requiring the creation of an
actual 1 in a register.
Or for ISAs with flags, have the mask already right-shifted by 1 so the bit
shifted out is the one we want. Then CF = result with no extra test.
Also an x86 missed optimization: BT reg,reg is very efficient (single uop) on
Intel and Ryzen, and avoids needing a 3-uop-on-Intel shift-by-CL or a mov reg,1
I'll report these ideas separately if/when I get around to it.