Description
Bugzilla Link | 49886 |
Version | trunk |
OS | All |
CC | @topperc,@RKSimon,@rotateright |
Extended Description
Note: this applies for both llvm.minnum
and llvm.maxnum
, although for the most part I'm just going to talk about the min case — both have this bug, though.
The documentation for llvm.minnum.*
says:
Follows the IEEE-754 semantics for minNum, except for handling of signaling
NaNs
But it goes on to say
If the operands compare equal, returns a value that compares equal to both
operands. This means that fmin(+/-0.0, +/-0.0) could return either -0.0 or
0.0.
These two statements are in contradiction, at as of IEEE-754 2019 (section 9.6, "Minimum and maximum operations"), which states:
minimumNumber(x, y) is
x
ifx<y
,y
ify < x
, and the number if one
operand is a number and the other is a NaN. For this operation, −0 compares
less than +0. Ifx = y
and signs are the same it is eitherx
ory
. If
both operands are NaNs, a quiet NaN is returned, according to 6.2. If either
operand is a signaling NaN, an invalid operation exception is signaled, but
unless both operands are NaNs, the signaling NaN is otherwise ignored and
not converted to a quiet NaN as stated in 6.2 for other operations.
In particular, "For this operation, −0 compares less than +0".
In Rust (rust-lang/rust#83984) we use llvm.minnum
and llvm.maxnum
for our normal float min/max operations, and would like these to be compliant with the IEEE-754 functions, with respect to -0.0.
Alternatively, if this cannot be fixed, it would be nice to have a pair of set of min/max functions that do implement the IEEE754 semantics (and also probably update the documentation to say that the handling of -0.0 differs from IEEE-754 as well)
P.S. We cannot use llvm.minimum
— While it would handle -0.0 properly, they handle NaNs completely differently, and we've documented the current "returns non-NaN for NaN input" behavior
P.P.S. I had no clue what component to put this under, sorry.