Rollup merge of #149563 - RalfJung:f-min-max, r=tgross35

f*::min/max: fix comparing with libm and IEEE operations

What we document actually doesn't match what libm does any more, libm got "fixed"/changed in https://sourceware.org/bugzilla/show_bug.cgi?id=20947. So better remove the remark. Instead, explicitly call out that this is a mix of `minNum` and `minimumNumber`.

Also fix the intrinsics which incorrectly claimed to be like `minNum`, but their intended SNaN behavior is actually different from that.

r? `@tgross35`
This commit is contained in:
Jacob Pratt 2025-12-05 23:26:37 -05:00 committed by GitHub
commit b53b824d06
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 88 additions and 80 deletions

View file

@ -2949,9 +2949,9 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
/// Returns the minimum of two `f16` values, ignoring NaN.
///
/// This behaves like IEEE 754-2008 minNum. In particular:
/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal
/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If
/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0`
/// and `-0.0`), either input may be returned non-deterministically.
///
/// Note that, unlike most intrinsics, this is safe to call;
/// it does not require an `unsafe` block.
@ -2965,9 +2965,9 @@ pub const fn minnumf16(x: f16, y: f16) -> f16;
/// Returns the minimum of two `f32` values, ignoring NaN.
///
/// This behaves like IEEE 754-2008 minNum. In particular:
/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal
/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If
/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0`
/// and `-0.0`), either input may be returned non-deterministically.
///
/// Note that, unlike most intrinsics, this is safe to call;
/// it does not require an `unsafe` block.
@ -2982,9 +2982,9 @@ pub const fn minnumf32(x: f32, y: f32) -> f32;
/// Returns the minimum of two `f64` values, ignoring NaN.
///
/// This behaves like IEEE 754-2008 minNum. In particular:
/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal
/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If
/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0`
/// and `-0.0`), either input may be returned non-deterministically.
///
/// Note that, unlike most intrinsics, this is safe to call;
/// it does not require an `unsafe` block.
@ -2999,9 +2999,9 @@ pub const fn minnumf64(x: f64, y: f64) -> f64;
/// Returns the minimum of two `f128` values, ignoring NaN.
///
/// This behaves like IEEE 754-2008 minNum. In particular:
/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal
/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If
/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0`
/// and `-0.0`), either input may be returned non-deterministically.
///
/// Note that, unlike most intrinsics, this is safe to call;
/// it does not require an `unsafe` block.
@ -3115,9 +3115,9 @@ pub const fn minimumf128(x: f128, y: f128) -> f128 {
/// Returns the maximum of two `f16` values, ignoring NaN.
///
/// This behaves like IEEE 754-2008 maxNum. In particular:
/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal
/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If
/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0`
/// and `-0.0`), either input may be returned non-deterministically.
///
/// Note that, unlike most intrinsics, this is safe to call;
/// it does not require an `unsafe` block.
@ -3131,9 +3131,9 @@ pub const fn maxnumf16(x: f16, y: f16) -> f16;
/// Returns the maximum of two `f32` values, ignoring NaN.
///
/// This behaves like IEEE 754-2008 maxNum. In particular:
/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal
/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If
/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0`
/// and `-0.0`), either input may be returned non-deterministically.
///
/// Note that, unlike most intrinsics, this is safe to call;
/// it does not require an `unsafe` block.
@ -3148,9 +3148,9 @@ pub const fn maxnumf32(x: f32, y: f32) -> f32;
/// Returns the maximum of two `f64` values, ignoring NaN.
///
/// This behaves like IEEE 754-2008 maxNum. In particular:
/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal
/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If
/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0`
/// and `-0.0`), either input may be returned non-deterministically.
///
/// Note that, unlike most intrinsics, this is safe to call;
/// it does not require an `unsafe` block.
@ -3165,9 +3165,9 @@ pub const fn maxnumf64(x: f64, y: f64) -> f64;
/// Returns the maximum of two `f128` values, ignoring NaN.
///
/// This behaves like IEEE 754-2008 maxNum. In particular:
/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal
/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If
/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0`
/// and `-0.0`), either input may be returned non-deterministically.
///
/// Note that, unlike most intrinsics, this is safe to call;
/// it does not require an `unsafe` block.

View file

@ -694,14 +694,15 @@ impl f128 {
/// Returns the maximum of the two numbers, ignoring NaN.
///
/// If exactly one of the arguments is NaN, then the other argument is returned. If both
/// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual
/// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such
/// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
/// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is
/// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked
/// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs
/// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned
/// non-deterministically.
///
/// This follows the IEEE 754-2008 semantics for `maxNum`, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids `maxNum`'s problems with associativity.
/// This also matches the behavior of libms `fmax`.
/// The handling of NaNs follows the IEEE 754-2019 semantics for `maximumNumber`, treating all
/// NaNs the same way to ensure the operation is associative. The handling of signed zeros
/// follows the IEEE 754-2008 semantics for `maxNum`.
///
/// ```
/// #![feature(f128)]
@ -725,14 +726,15 @@ impl f128 {
/// Returns the minimum of the two numbers, ignoring NaN.
///
/// If exactly one of the arguments is NaN, then the other argument is returned. If both
/// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual
/// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such
/// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
/// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is
/// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked
/// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs
/// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned
/// non-deterministically.
///
/// This follows the IEEE 754-2008 semantics for `minNum`, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids `minNum`'s problems with associativity.
/// This also matches the behavior of libms `fmin`.
/// The handling of NaNs follows the IEEE 754-2019 semantics for `minimumNumber`, treating all
/// NaNs the same way to ensure the operation is associative. The handling of signed zeros
/// follows the IEEE 754-2008 semantics for `minNum`.
///
/// ```
/// #![feature(f128)]

View file

@ -687,14 +687,15 @@ impl f16 {
/// Returns the maximum of the two numbers, ignoring NaN.
///
/// If exactly one of the arguments is NaN, then the other argument is returned. If both
/// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual
/// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such
/// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
/// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is
/// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked
/// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs
/// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned
/// non-deterministically.
///
/// This follows the IEEE 754-2008 semantics for `maxNum`, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids `maxNum`'s problems with associativity.
/// This also matches the behavior of libms `fmax`.
/// The handling of NaNs follows the IEEE 754-2019 semantics for `maximumNumber`, treating all
/// NaNs the same way to ensure the operation is associative. The handling of signed zeros
/// follows the IEEE 754-2008 semantics for `maxNum`.
///
/// ```
/// #![feature(f16)]
@ -717,14 +718,15 @@ impl f16 {
/// Returns the minimum of the two numbers, ignoring NaN.
///
/// If exactly one of the arguments is NaN, then the other argument is returned. If both
/// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual
/// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such
/// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
/// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is
/// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked
/// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs
/// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned
/// non-deterministically.
///
/// This follows the IEEE 754-2008 semantics for `minNum`, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids `minNum`'s problems with associativity.
/// This also matches the behavior of libms `fmin`.
/// The handling of NaNs follows the IEEE 754-2019 semantics for `minimumNumber`, treating all
/// NaNs the same way to ensure the operation is associative. The handling of signed zeros
/// follows the IEEE 754-2008 semantics for `minNum`.
///
/// ```
/// #![feature(f16)]

View file

@ -897,14 +897,15 @@ impl f32 {
/// Returns the maximum of the two numbers, ignoring NaN.
///
/// If exactly one of the arguments is NaN, then the other argument is returned. If both
/// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual
/// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such
/// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
/// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is
/// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked
/// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs
/// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned
/// non-deterministically.
///
/// This follows the IEEE 754-2008 semantics for `maxNum`, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids `maxNum`'s problems with associativity.
/// This also matches the behavior of libms `fmax`.
/// The handling of NaNs follows the IEEE 754-2019 semantics for `maximumNumber`, treating all
/// NaNs the same way to ensure the operation is associative. The handling of signed zeros
/// follows the IEEE 754-2008 semantics for `maxNum`.
///
/// ```
/// let x = 1.0f32;
@ -923,14 +924,15 @@ impl f32 {
/// Returns the minimum of the two numbers, ignoring NaN.
///
/// If exactly one of the arguments is NaN, then the other argument is returned. If both
/// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual
/// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such
/// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
/// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is
/// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked
/// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs
/// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned
/// non-deterministically.
///
/// This follows the IEEE 754-2008 semantics for `minNum`, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids `minNum`'s problems with associativity.
/// This also matches the behavior of libms `fmin`.
/// The handling of NaNs follows the IEEE 754-2019 semantics for `minimumNumber`, treating all
/// NaNs the same way to ensure the operation is associative. The handling of signed zeros
/// follows the IEEE 754-2008 semantics for `minNum`.
///
/// ```
/// let x = 1.0f32;

View file

@ -915,14 +915,15 @@ impl f64 {
/// Returns the maximum of the two numbers, ignoring NaN.
///
/// If exactly one of the arguments is NaN, then the other argument is returned. If both
/// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual
/// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such
/// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
/// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is
/// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked
/// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs
/// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned
/// non-deterministically.
///
/// This follows the IEEE 754-2008 semantics for `maxNum`, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids `maxNum`'s problems with associativity.
/// This also matches the behavior of libms `fmax`.
/// The handling of NaNs follows the IEEE 754-2019 semantics for `maximumNumber`, treating all
/// NaNs the same way to ensure the operation is associative. The handling of signed zeros
/// follows the IEEE 754-2008 semantics for `maxNum`.
///
/// ```
/// let x = 1.0_f64;
@ -941,14 +942,15 @@ impl f64 {
/// Returns the minimum of the two numbers, ignoring NaN.
///
/// If exactly one of the arguments is NaN, then the other argument is returned. If both
/// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual
/// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such
/// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
/// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is
/// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked
/// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs
/// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned
/// non-deterministically.
///
/// This follows the IEEE 754-2008 semantics for `minNum`, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids `minNum`'s problems with associativity.
/// This also matches the behavior of libms `fmin`.
/// The handling of NaNs follows the IEEE 754-2019 semantics for `minimumNumber`, treating all
/// NaNs the same way to ensure the operation is associative. The handling of signed zeros
/// follows the IEEE 754-2008 semantics for `minNum`.
///
/// ```
/// let x = 1.0_f64;