Skip to content

Commit 500033d

Browse files
committed
intrinsics: clarify float min/max behavios for NaNs and signed zeros
1 parent c268b39 commit 500033d

File tree

2 files changed

+90
-34
lines changed

2 files changed

+90
-34
lines changed

compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,15 @@ pub(crate) enum MinMax {
4242
Minimum,
4343
/// The IEEE `MinNum` operation - see `f32::min` etc
4444
/// In particular, if the inputs are `-0.0` and `+0.0`, the result is non-deterministic,
45-
/// and is one argument is NaN, the other one is returned.
45+
/// and if one argument is NaN, the other one is returned.
4646
MinNum,
4747
/// The IEEE `Maximum` operation - see `f32::maximum` etc
4848
/// In particular, `-0.0` is considered smaller than `+0.0` and
4949
/// if either input is NaN, the result is NaN.
5050
Maximum,
5151
/// The IEEE `MaxNum` operation - see `f32::max` etc
5252
/// In particular, if the inputs are `-0.0` and `+0.0`, the result is non-deterministic,
53-
/// and is one argument is NaN, the other one is returned.
53+
/// and if one argument is NaN, the other one is returned.
5454
MaxNum,
5555
}
5656

library/core/src/intrinsics/mod.rs

Lines changed: 88 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2947,61 +2947,77 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize);
29472947
#[rustc_intrinsic]
29482948
pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
29492949

2950-
/// Returns the minimum (IEEE 754-2008 minNum) of two `f16` values.
2950+
/// Returns the minimum of two `f16` values, ignoring NaN.
2951+
///
2952+
/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal
2953+
/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
2954+
/// The last point makes this not quite the same as IEEE 754-2008 minNum.
29512955
///
29522956
/// Note that, unlike most intrinsics, this is safe to call;
29532957
/// it does not require an `unsafe` block.
29542958
/// Therefore, implementations must not require the user to uphold
29552959
/// any safety invariants.
29562960
///
2957-
/// The stabilized version of this intrinsic is
2958-
/// [`f16::min`]
2961+
/// The stabilized version of this intrinsic is [`f16::min`].
29592962
#[rustc_nounwind]
29602963
#[rustc_intrinsic]
29612964
pub const fn minnumf16(x: f16, y: f16) -> f16;
29622965

2963-
/// Returns the minimum (IEEE 754-2008 minNum) of two `f32` values.
2966+
/// Returns the minimum of two `f32` values, ignoring NaN.
2967+
///
2968+
/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal
2969+
/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
2970+
/// The last point makes this not quite the same as IEEE 754-2008 minNum.
29642971
///
29652972
/// Note that, unlike most intrinsics, this is safe to call;
29662973
/// it does not require an `unsafe` block.
29672974
/// Therefore, implementations must not require the user to uphold
29682975
/// any safety invariants.
29692976
///
2970-
/// The stabilized version of this intrinsic is
2971-
/// [`f32::min`]
2977+
/// The stabilized version of this intrinsic is [`f32::min`].
29722978
#[rustc_nounwind]
29732979
#[rustc_intrinsic_const_stable_indirect]
29742980
#[rustc_intrinsic]
29752981
pub const fn minnumf32(x: f32, y: f32) -> f32;
29762982

2977-
/// Returns the minimum (IEEE 754-2008 minNum) of two `f64` values.
2983+
/// Returns the minimum of two `f64` values, ignoring NaN.
2984+
///
2985+
/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal
2986+
/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
2987+
/// The last point makes this not quite the same as IEEE 754-2008 minNum.
29782988
///
29792989
/// Note that, unlike most intrinsics, this is safe to call;
29802990
/// it does not require an `unsafe` block.
29812991
/// Therefore, implementations must not require the user to uphold
29822992
/// any safety invariants.
29832993
///
2984-
/// The stabilized version of this intrinsic is
2985-
/// [`f64::min`]
2994+
/// The stabilized version of this intrinsic is [`f64::min`].
29862995
#[rustc_nounwind]
29872996
#[rustc_intrinsic_const_stable_indirect]
29882997
#[rustc_intrinsic]
29892998
pub const fn minnumf64(x: f64, y: f64) -> f64;
29902999

2991-
/// Returns the minimum (IEEE 754-2008 minNum) of two `f128` values.
3000+
/// Returns the minimum of two `f128` values, ignoring NaN.
3001+
///
3002+
/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal
3003+
/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
3004+
/// The last point makes this not quite the same as IEEE 754-2008 minNum.
29923005
///
29933006
/// Note that, unlike most intrinsics, this is safe to call;
29943007
/// it does not require an `unsafe` block.
29953008
/// Therefore, implementations must not require the user to uphold
29963009
/// any safety invariants.
29973010
///
2998-
/// The stabilized version of this intrinsic is
2999-
/// [`f128::min`]
3011+
/// The stabilized version of this intrinsic is [`f128::min`].
30003012
#[rustc_nounwind]
30013013
#[rustc_intrinsic]
30023014
pub const fn minnumf128(x: f128, y: f128) -> f128;
30033015

3004-
/// Returns the minimum (IEEE 754-2019 minimum) of two `f16` values.
3016+
/// Returns the minimum of two `f16` values, propagating NaN.
3017+
///
3018+
/// This behaves like IEEE 754-2019 minimum. In particular:
3019+
/// If one of the arguments is NaN, then a NaN is returned using the usual NaN propagation rules.
3020+
/// For this operation, -0.0 is considered to be strictly less than +0.0.
30053021
///
30063022
/// Note that, unlike most intrinsics, this is safe to call;
30073023
/// it does not require an `unsafe` block.
@@ -3022,7 +3038,11 @@ pub const fn minimumf16(x: f16, y: f16) -> f16 {
30223038
}
30233039
}
30243040

3025-
/// Returns the minimum (IEEE 754-2019 minimum) of two `f32` values.
3041+
/// Returns the minimum of two `f32` values, propagating NaN.
3042+
///
3043+
/// This behaves like IEEE 754-2019 minimum. In particular:
3044+
/// If one of the arguments is NaN, then a NaN is returned using the usual NaN propagation rules.
3045+
/// For this operation, -0.0 is considered to be strictly less than +0.0.
30263046
///
30273047
/// Note that, unlike most intrinsics, this is safe to call;
30283048
/// it does not require an `unsafe` block.
@@ -3043,7 +3063,11 @@ pub const fn minimumf32(x: f32, y: f32) -> f32 {
30433063
}
30443064
}
30453065

3046-
/// Returns the minimum (IEEE 754-2019 minimum) of two `f64` values.
3066+
/// Returns the minimum of two `f64` values, propagating NaN.
3067+
///
3068+
/// This behaves like IEEE 754-2019 minimum. In particular:
3069+
/// If one of the arguments is NaN, then a NaN is returned using the usual NaN propagation rules.
3070+
/// For this operation, -0.0 is considered to be strictly less than +0.0.
30473071
///
30483072
/// Note that, unlike most intrinsics, this is safe to call;
30493073
/// it does not require an `unsafe` block.
@@ -3064,7 +3088,11 @@ pub const fn minimumf64(x: f64, y: f64) -> f64 {
30643088
}
30653089
}
30663090

3067-
/// Returns the minimum (IEEE 754-2019 minimum) of two `f128` values.
3091+
/// Returns the minimum of two `f128` values, propagating NaN.
3092+
///
3093+
/// This behaves like IEEE 754-2019 minimum. In particular:
3094+
/// If one of the arguments is NaN, then a NaN is returned using the usual NaN propagation rules.
3095+
/// For this operation, -0.0 is considered to be strictly less than +0.0.
30683096
///
30693097
/// Note that, unlike most intrinsics, this is safe to call;
30703098
/// it does not require an `unsafe` block.
@@ -3085,61 +3113,77 @@ pub const fn minimumf128(x: f128, y: f128) -> f128 {
30853113
}
30863114
}
30873115

3088-
/// Returns the maximum (IEEE 754-2008 maxNum) of two `f16` values.
3116+
/// Returns the maximum of two `f16` values, ignoring NaN.
3117+
///
3118+
/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal
3119+
/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
3120+
/// The last point makes this not quite the same as IEEE 754-2008 maxNum.
30893121
///
30903122
/// Note that, unlike most intrinsics, this is safe to call;
30913123
/// it does not require an `unsafe` block.
30923124
/// Therefore, implementations must not require the user to uphold
30933125
/// any safety invariants.
30943126
///
3095-
/// The stabilized version of this intrinsic is
3096-
/// [`f16::max`]
3127+
/// The stabilized version of this intrinsic is [`f16::max`].
30973128
#[rustc_nounwind]
30983129
#[rustc_intrinsic]
30993130
pub const fn maxnumf16(x: f16, y: f16) -> f16;
31003131

3101-
/// Returns the maximum (IEEE 754-2008 maxNum) of two `f32` values.
3132+
/// Returns the maximum of two `f32` values, ignroing NaN.
3133+
///
3134+
/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal
3135+
/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
3136+
/// The last point makes this not quite the same as IEEE 754-2008 maxNum.
31023137
///
31033138
/// Note that, unlike most intrinsics, this is safe to call;
31043139
/// it does not require an `unsafe` block.
31053140
/// Therefore, implementations must not require the user to uphold
31063141
/// any safety invariants.
31073142
///
3108-
/// The stabilized version of this intrinsic is
3109-
/// [`f32::max`]
3143+
/// The stabilized version of this intrinsic is [`f32::max`].
31103144
#[rustc_nounwind]
31113145
#[rustc_intrinsic_const_stable_indirect]
31123146
#[rustc_intrinsic]
31133147
pub const fn maxnumf32(x: f32, y: f32) -> f32;
31143148

3115-
/// Returns the maximum (IEEE 754-2008 maxNum) of two `f64` values.
3149+
/// Returns the maximum of two `f64` values, ignoring NaN.
3150+
///
3151+
/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal
3152+
/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
3153+
/// The last point makes this not quite the same as IEEE 754-2008 maxNum.
31163154
///
31173155
/// Note that, unlike most intrinsics, this is safe to call;
31183156
/// it does not require an `unsafe` block.
31193157
/// Therefore, implementations must not require the user to uphold
31203158
/// any safety invariants.
31213159
///
3122-
/// The stabilized version of this intrinsic is
3123-
/// [`f64::max`]
3160+
/// The stabilized version of this intrinsic is [`f64::max`].
31243161
#[rustc_nounwind]
31253162
#[rustc_intrinsic_const_stable_indirect]
31263163
#[rustc_intrinsic]
31273164
pub const fn maxnumf64(x: f64, y: f64) -> f64;
31283165

3129-
/// Returns the maximum (IEEE 754-2008 maxNum) of two `f128` values.
3166+
/// Returns the maximum of two `f128` values, ignoring NaN.
3167+
///
3168+
/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal
3169+
/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
3170+
/// The last point makes this not quite the same as IEEE 754-2008 maxNum.
31303171
///
31313172
/// Note that, unlike most intrinsics, this is safe to call;
31323173
/// it does not require an `unsafe` block.
31333174
/// Therefore, implementations must not require the user to uphold
31343175
/// any safety invariants.
31353176
///
3136-
/// The stabilized version of this intrinsic is
3137-
/// [`f128::max`]
3177+
/// The stabilized version of this intrinsic is [`f128::max`].
31383178
#[rustc_nounwind]
31393179
#[rustc_intrinsic]
31403180
pub const fn maxnumf128(x: f128, y: f128) -> f128;
31413181

3142-
/// Returns the maximum (IEEE 754-2019 maximum) of two `f16` values.
3182+
/// Returns the maximum of two `f16` values, propagating NaN.
3183+
///
3184+
/// This behaves like IEEE 754-2019 maximum. In particular:
3185+
/// If one of the arguments is NaN, then a NaN is returned using the usual NaN propagation rules.
3186+
/// For this operation, -0.0 is considered to be strictly less than +0.0.
31433187
///
31443188
/// Note that, unlike most intrinsics, this is safe to call;
31453189
/// it does not require an `unsafe` block.
@@ -3159,7 +3203,11 @@ pub const fn maximumf16(x: f16, y: f16) -> f16 {
31593203
}
31603204
}
31613205

3162-
/// Returns the maximum (IEEE 754-2019 maximum) of two `f32` values.
3206+
/// Returns the maximum of two `f32` values, propagating NaN.
3207+
///
3208+
/// This behaves like IEEE 754-2019 maximum. In particular:
3209+
/// If one of the arguments is NaN, then a NaN is returned using the usual NaN propagation rules.
3210+
/// For this operation, -0.0 is considered to be strictly less than +0.0.
31633211
///
31643212
/// Note that, unlike most intrinsics, this is safe to call;
31653213
/// it does not require an `unsafe` block.
@@ -3179,7 +3227,11 @@ pub const fn maximumf32(x: f32, y: f32) -> f32 {
31793227
}
31803228
}
31813229

3182-
/// Returns the maximum (IEEE 754-2019 maximum) of two `f64` values.
3230+
/// Returns the maximum of two `f64` values, propagating NaN.
3231+
///
3232+
/// This behaves like IEEE 754-2019 maximum. In particular:
3233+
/// If one of the arguments is NaN, then a NaN is returned using the usual NaN propagation rules.
3234+
/// For this operation, -0.0 is considered to be strictly less than +0.0.
31833235
///
31843236
/// Note that, unlike most intrinsics, this is safe to call;
31853237
/// it does not require an `unsafe` block.
@@ -3199,7 +3251,11 @@ pub const fn maximumf64(x: f64, y: f64) -> f64 {
31993251
}
32003252
}
32013253

3202-
/// Returns the maximum (IEEE 754-2019 maximum) of two `f128` values.
3254+
/// Returns the maximum of two `f128` values, propagating NaN.
3255+
///
3256+
/// This behaves like IEEE 754-2019 maximum. In particular:
3257+
/// If one of the arguments is NaN, then a NaN is returned using the usual NaN propagation rules.
3258+
/// For this operation, -0.0 is considered to be strictly less than +0.0.
32033259
///
32043260
/// Note that, unlike most intrinsics, this is safe to call;
32053261
/// it does not require an `unsafe` block.

0 commit comments

Comments
 (0)