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.