On 10/27/16 14:52, Bernd Schmidt wrote:
> On 10/27/2016 01:27 PM, Bernd Edlinger wrote:
>> Hi,
>>
>> by code reading I became aware that libgcc can call count_leading_zeros
>> in certain cases which can give undefined results.  This happens on
>> signed int128 -> float or double conversions, when the int128 is in
>> the range
>> INT64_MAX+1 to UINT64_MAX.
>
> Did you actually observe this? Because, prior to this code,
>
>> Index: libgcc2.c
>> ===================================================================
>> --- libgcc2.c    (revision 241400)
>> +++ libgcc2.c    (working copy)
>> @@ -1643,6 +1643,11 @@
>>      hi = -(UWtype) hi;
>>
>>    UWtype count, shift;
>> +#if !defined (COUNT_LEADING_ZEROS_0) || COUNT_LEADING_ZEROS_0 !=
>> W_TYPE_SIZE
>> +  if (hi == 0)
>> +    count = W_TYPE_SIZE;
>> +  else
>> +#endif
>>    count_leading_zeros (count, hi);
>>
>>    /* No leading bits means u == minimum.  */
>
> we have:
>
>   /* If there are no high bits set, fall back to one conversion.  */
>   if ((Wtype)u == u)
>     return (FSTYPE)(Wtype)u;
>
>   /* Otherwise, find the power of two.  */
>   Wtype hi = u >> W_TYPE_SIZE;
>
> which looks to me like it ensures that hi is != 0.
>

No.  I have been there in the debugger.

But with Wtype = long long
and thus (long long)(2^64-1) = -1LL
and the if is not taken, as (__int128)-1LL != (__int128)(2^64-1).

but 2^64-1 >> 64  =  0.

Now it the BSR instruction is used, with in=out=si,
it is not specified, what will be the result in this case,
on my machine AMD64-someting, it left the si register untouched.
and the function continued, as if count was 63 in that case, but
to be correct, it should be 64.

In the function below we have if ((UWtype)u == u)
that actually ensures hi != 0.


Bernd.

Reply via email to