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