__builtin_isnanl() and invalid x87 80-bit floating point numbers

Liu Hao lh_mouse@126.com
Sat May 13 16:43:00 GMT 2017


On 2017/5/13 23:58, Vincent Lefevre wrote:
> On 2017-05-13 11:06:06 +0800, Liu Hao wrote:
>> On 2017/5/13 10:25, Vincent Lefevre wrote:
>>> On 2017-05-12 23:46:09 +0800, Liu Hao wrote:
>>> But if you do this, you're out of scope of the standards.
>>>
>>> Moreover, I suppose that you will also get a floating-point exception
>>> on a signaling NaN, in which case, on this example, this isn't
>>> distinguishable from a signaling NaN.
>                             ^^^^^^^^^
>> A QNaN doesn't generate an exception regardless of the x87 control word.
> 
> It isn't because the value doesn't generate a trap. FP exceptions
> are a different notion. They are generated by operations, not by
> reading values.
Reading NaNs (regardless of signaling-ness) or invalid values doesn't 
raise exceptions. However:

(This is a rough conclusion from Intel manuals and any disagreement is 
unintentional. Please check Intel manuals for sure.)

0) If an arithmetic operation is performed on a QNaN, the result is a
    QNaN, no exception is raised. (This out of scope in this topic.)
1) If an arithmetic operation is performed on a SNaN, an #IA exception
    is raised (regardless of whether it is masked or not, similarly
    hereinafter).
2) If the `FST` or `FSTP` instruction is used to store a SNaN to a
    memory location and that location is not a `TBYTE` (ten bytes), an
    #IA exception is raised. The SNaN is copied as-is when stored as
    the 80-bit extended precision format without any exceptions raised.
3) If an arithmetic operation is performed on an invalid operand, the
    same happens with 1).
4) If the `FST` or `FSTP` instruction is used to store an invalid
    operand to a memory location, an #IA exception is raised regardless
    of size of that location.

Since case 2) and 4) differ, a SNaN and an invalid operand are *not* 
indistinguishable.

>> Let's try `=` which corresponds to the IEEE 754 equality operator too:
> 
> No, in C, '=' is an assignment operator.
Good catch, and apparently it was an oversight. I meant to say 
'assignment operator'.

> The printf is not a processor instruction. I would see this as a bug
> in the C library. Otherwise there's a clear contradiction with the
> behavior of ==, which directly corresponds to an x86 instruction.
> 
I agree that printing `nan` for something not a NaN (double negation 
intended) is a bug.

> But they might also see this as undefined behavior, in which case
> long double mustn't be documented as being the x86 double-extended
> format.
> 
ISO C permits implementations to define additional macro constants for 
the `fpclassify` macro that match the regexp `FP_[A-Z][A-Za-z0-9_]*`. 
The only problem we have at the moment is that we don't have a constant 
for invalid operands.

-- 
Best regards,
LH_Mouse



More information about the Gcc-help mailing list