Skip to content

SimplifyCFG could emit comparisons instead of tables in simple cases #61366

@scottmcm

Description

@scottmcm

I was experimenting with various forms of this to see what's best, so I tried the "just do it the obvious way":

#include <stdint.h>
bool is_ge(int8_t c) {
    switch (c) {
        case -1: return false;
        case 0: return true;
        case 1: return true;
    }

    __builtin_unreachable();
}

But that comes out with surprisingly-complicated codegen: https://cpp.godbolt.org/z/bfYb91hdj

is_ge(signed char):                              # @is_ge(signed char)
        inc     dil
        movzx   eax, dil
        and     eax, 7
        mov     ecx, 6
        bt      ecx, eax
        setb    al
        ret

This particular case could of course just be x ULT 2, but even the "make a table and shift" could be better. For example, I think it could avoid the range shifting by using something like ((0x3 >> (c&3)) & 1) == 0, for smaller constants and fewer instructions

is_ge_alt(unsigned char):                          # @is_ge_alt(unsigned char)
        and     edi, 3
        mov     eax, 3
        bt      eax, edi
        setb    al
        ret

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions