On 14/03/2024 12:03 pm, Andreas Schwab wrote:
> On Mär 14 2024, Andrew Cooper via Gcc wrote:
>
>> so any known-constant value can be folded.  What I'm dealing with is the
>> remainder of the cases.
> Which cases remain?

None, thanks to the answers on this thread.

The overall structure I've got now is:

unsigned int ffs(unsigned int x)
{
    if ( __builtin_constant_p(x) )
        return __builtin_ffs(x);  // Allows constant folding

#ifndef arch_ffs
#define arch_ffs __builtin_ffs
#endif

    return arch_ffs(x);
}

And for x86's arch_ffs(),

unsigned int arch_ffs(unsigned int x)
{
    unsigned int res;

    if ( __builtin_constant_p(x > 0) && x > 0 )
    {
        // Well defined when x is known non-zero
        asm("bsf %1, %0" : "=r"(res) : "rm"(x));
    }
    else
    {
        // The architects say this is safe even for 0.
        res = -1;
        asm("bsf %1, %0" : "+r"(res) : "rm"(x));
    }

    return res + 1;
}


This gives the same code gen as before (give or take some register
shuffling), without having to rely on the programmer to remember to get
their ffs()'s separated from their __ffs()'s as it pertains to undefined
input.

The other architectures which have better-defined instructions don't
need any of these games to retain the same good code-gen that is
currently expressed with a maze of subtly-different functions.

~Andrew

Reply via email to