Does `isless` trap on signaling NaN?

In IEEE-754 [0], the description implies that isless and other “quiet comparison” operations (isgreater, isgreatequal, …) still raises an exception.

In C standard 7.12.14.3 [1], it describes how isless does not raise any exception for unordered operands…

The isless macro determines whether its first argument is less than its second argument. The value of isless(x, y) is always equal to (x) < (y); howev er, unlike (x) < (y), isless(x, y) does not raise the ‘‘invalid’’ floating-point exception when x and y are unordered.

Also in C standard F.2.1 [1], it explicitly states that signaling NaNs are not included in it.

This specification does not define the behavior of signaling NaNs.346)

I guess this gives us a conclusion of the following (O stands for raise exception, X stands for don’t raise exception)

             | sNaN | qNaN
----------------------------
isless(x, y) | O    |  X
----------------------------
raw op `<`   | O    |  O

[0] Quoting from IEEE-754, “the unordered-quiet reversed predicate (X ?>= Y) is different in that it does not signal an invalid operation exception when X and Y are unordered (unless X or Y is a signaling NaN).”
[1] C11 standard https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf


Should the FIXME [2] under CGBuiltin.cpp be removed then? Since we “should” trap on sNaN for isless?

@kpneal

[2] https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/CGBuiltin.cpp#L2979

Newer drafts of C contain updated text. I’m using N2596 which isn’t the most recent draft of C2x, but it does incorporate several modifications to Annex F.

Notably, F.2.1 paragraph 3 now says that:

This annex does not require the full support for signaling NaNs specified in IEC 60559. This annex uses the term NaN, unless explicitly qualified, to denote quiet NaNs. Where specification of signaling NaNs is not provided, the behavior of signaling NaNs is implementation-defined (either treated as an IEC 60559 quiet NaN or treated as an IEC 60559 signaling NaN).

Also, F.3 now includes a table that explicitly maps IEEE 754-2019 operations to C expressions (and vice versa). This clarifies that x < y implements compareSignalingLess, while isless implements compareQuietLess.

Now LLVM generally does not support SNaNs correctly in general. This is roughly equivalent to choosing to treat signaling NaNs as quite NaNs as provided for in F.2.1p3. When -fp-model=strict is provided (or using FENV_ACCESS ON), however, the intent should be to implement SNaNs as if they were signaling.

The correct implementation in LLVM is to lower x < y to llvm.experimental.constrained.fcmps and isless(x, y) to llvm.experimental.constrained.fcmp, at least when strictfp is enabled. It looks like the code already does this correctly (Compiler Explorer), so yes, the comment should be removed as inaccurate.

Thank you for the reply.

Comment removed.
https://reviews.llvm.org/rG10409bf86e58320443db5c5ea2adf5e437104ee9