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.

Reply via email to