https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97445
--- Comment #43 from Christophe Leroy <christophe.leroy at csgroup dot eu> ---
(In reply to Christophe Leroy from comment #42)
> (In reply to Jakub Jelinek from comment #41)
> > It is documented to be undefined:
> >  -- Built-in Function: int __builtin_clz (unsigned int x)
> >      Returns the number of leading 0-bits in X, starting at the most
> >      significant bit position.  If X is 0, the result is undefined.
> > Especially GCC 11 (but e.g. clang too) will e.g. during value range
> > propagation assume that e.g. the builtin return value will be only 0 to 31,
> > not to 32, etc.
> > The portable way how to write this is x ? __builtin_clz (x) :
> > whatever_value_you_want_for_clz_0;
> > and the compiler should recognize that and if the instruction is well
> > defined for 0 and matches your choice, use optimal sequence.
> 
> int f(int x)
> {
>       return x ? __builtin_clz(x) : 32;
> }
> 
> Is compiled into (with -O2):
> 
> 00000000 <f>:
>    0: 2c 03 00 00     cmpwi   r3,0
>    4: 40 82 00 0c     bne     10 <f+0x10>
>    8: 38 60 00 20     li      r3,32
>    c: 4e 80 00 20     blr
>   10: 7c 63 00 34     cntlzw  r3,r3
>   14: 4e 80 00 20     blr
> 
> 
> 
> Allthough
> 
> int g(void)
> {

int g(int x)
{
        return __builtin_clz(0);
}

Gives

00000018 <g>:
  18:   38 60 00 20     li      r3,32
  1c:   4e 80 00 20     blr

Reply via email to