From 8440f8d1b3f4cda3a14eb8c810a5850f3e3ae404 Mon Sep 17 00:00:00 2001 From: Anmol Mishra Date: Fri, 20 Mar 2026 21:58:24 +0000 Subject: [PATCH] Enforce deterministic signed zero behavior in min/max/clamp This drops the `nsz` tag from `minimum_number_nsz` and `maximum_number_nsz` intrinsics, and updates their fallback implementation in `core::intrinsics` to consistently order `-0.0 < +0.0`. `clamp` is also rewritten to use `self.max(min).min(max)` which uses the newly ordered min/max. Fixes #154061 --- .../src/intrinsics/mod.rs | 16 +-- compiler/rustc_codegen_llvm/src/intrinsic.rs | 19 ++-- .../src/interpret/intrinsics.rs | 16 +-- .../rustc_hir_analysis/src/check/intrinsic.rs | 32 +++--- compiler/rustc_span/src/symbol.rs | 16 +-- library/core/src/intrinsics/mod.rs | 104 +++++++++++------- library/core/src/num/f128.rs | 15 +-- library/core/src/num/f16.rs | 15 +-- library/core/src/num/f32.rs | 15 +-- library/core/src/num/f64.rs | 15 +-- 10 files changed, 128 insertions(+), 135 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 8b112e695275a..d91f9f9f5be92 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -1266,7 +1266,7 @@ fn codegen_regular_intrinsic_call<'tcx>( ret.write_cvalue(fx, val); } - sym::minimum_number_nsz_f16 => { + sym::minimum_number_f16 => { intrinsic_args!(fx, args => (a, b); intrinsic); let a = a.load_scalar(fx); let b = b.load_scalar(fx); @@ -1275,7 +1275,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f16)); ret.write_cvalue(fx, val); } - sym::minimum_number_nsz_f32 => { + sym::minimum_number_f32 => { intrinsic_args!(fx, args => (a, b); intrinsic); let a = a.load_scalar(fx); let b = b.load_scalar(fx); @@ -1284,7 +1284,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f32)); ret.write_cvalue(fx, val); } - sym::minimum_number_nsz_f64 => { + sym::minimum_number_f64 => { intrinsic_args!(fx, args => (a, b); intrinsic); let a = a.load_scalar(fx); let b = b.load_scalar(fx); @@ -1293,7 +1293,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f64)); ret.write_cvalue(fx, val); } - sym::minimum_number_nsz_f128 => { + sym::minimum_number_f128 => { intrinsic_args!(fx, args => (a, b); intrinsic); let a = a.load_scalar(fx); let b = b.load_scalar(fx); @@ -1302,7 +1302,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f128)); ret.write_cvalue(fx, val); } - sym::maximum_number_nsz_f16 => { + sym::maximum_number_f16 => { intrinsic_args!(fx, args => (a, b); intrinsic); let a = a.load_scalar(fx); let b = b.load_scalar(fx); @@ -1311,7 +1311,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f16)); ret.write_cvalue(fx, val); } - sym::maximum_number_nsz_f32 => { + sym::maximum_number_f32 => { intrinsic_args!(fx, args => (a, b); intrinsic); let a = a.load_scalar(fx); let b = b.load_scalar(fx); @@ -1320,7 +1320,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f32)); ret.write_cvalue(fx, val); } - sym::maximum_number_nsz_f64 => { + sym::maximum_number_f64 => { intrinsic_args!(fx, args => (a, b); intrinsic); let a = a.load_scalar(fx); let b = b.load_scalar(fx); @@ -1329,7 +1329,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f64)); ret.write_cvalue(fx, val); } - sym::maximum_number_nsz_f128 => { + sym::maximum_number_f128 => { intrinsic_args!(fx, args => (a, b); intrinsic); let a = a.load_scalar(fx); let b = b.load_scalar(fx); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index cc6ecee60b0e4..e53dba534abf4 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -185,14 +185,14 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let simple = call_simple_intrinsic(self, name, args); let llval = match name { _ if simple.is_some() => simple.unwrap(), - sym::minimum_number_nsz_f16 - | sym::minimum_number_nsz_f32 - | sym::minimum_number_nsz_f64 - | sym::minimum_number_nsz_f128 - | sym::maximum_number_nsz_f16 - | sym::maximum_number_nsz_f32 - | sym::maximum_number_nsz_f64 - | sym::maximum_number_nsz_f128 + sym::minimum_number_f16 + | sym::minimum_number_f32 + | sym::minimum_number_f64 + | sym::minimum_number_f128 + | sym::maximum_number_f16 + | sym::maximum_number_f32 + | sym::maximum_number_f64 + | sym::maximum_number_f128 // Need at least LLVM 22 for `min/maximumnum` to not crash LLVM. if crate::llvm_util::get_version() >= (22, 0, 0) => { @@ -206,9 +206,6 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { &[args[0].layout.immediate_llvm_type(self.cx)], &[args[0].immediate(), args[1].immediate()], ); - // `nsz` on minimumnum/maximumnum is special: its only effect is to make - // signed-zero ordering non-deterministic. - unsafe { llvm::LLVMRustSetNoSignedZeros(call) }; call } sym::ptr_mask => { diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index d5f69d78ea6ae..b1ee1735e4bd7 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -526,16 +526,16 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_scalar(Scalar::from_target_usize(align.bytes(), self), dest)?; } - sym::minimum_number_nsz_f16 => { + sym::minimum_number_f16 => { self.float_minmax_intrinsic::(args, MinMax::MinimumNumberNsz, dest)? } - sym::minimum_number_nsz_f32 => { + sym::minimum_number_f32 => { self.float_minmax_intrinsic::(args, MinMax::MinimumNumberNsz, dest)? } - sym::minimum_number_nsz_f64 => { + sym::minimum_number_f64 => { self.float_minmax_intrinsic::(args, MinMax::MinimumNumberNsz, dest)? } - sym::minimum_number_nsz_f128 => { + sym::minimum_number_f128 => { self.float_minmax_intrinsic::(args, MinMax::MinimumNumberNsz, dest)? } @@ -548,16 +548,16 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } sym::minimumf128 => self.float_minmax_intrinsic::(args, MinMax::Minimum, dest)?, - sym::maximum_number_nsz_f16 => { + sym::maximum_number_f16 => { self.float_minmax_intrinsic::(args, MinMax::MaximumNumberNsz, dest)? } - sym::maximum_number_nsz_f32 => { + sym::maximum_number_f32 => { self.float_minmax_intrinsic::(args, MinMax::MaximumNumberNsz, dest)? } - sym::maximum_number_nsz_f64 => { + sym::maximum_number_f64 => { self.float_minmax_intrinsic::(args, MinMax::MaximumNumberNsz, dest)? } - sym::maximum_number_nsz_f128 => { + sym::maximum_number_f128 => { self.float_minmax_intrinsic::(args, MinMax::MaximumNumberNsz, dest)? } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 47420997a509a..a137819d88302 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -147,18 +147,18 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::logf32 | sym::logf64 | sym::logf128 - | sym::maximum_number_nsz_f16 - | sym::maximum_number_nsz_f32 - | sym::maximum_number_nsz_f64 - | sym::maximum_number_nsz_f128 + | sym::maximum_number_f16 + | sym::maximum_number_f32 + | sym::maximum_number_f64 + | sym::maximum_number_f128 | sym::maximumf16 | sym::maximumf32 | sym::maximumf64 | sym::maximumf128 - | sym::minimum_number_nsz_f16 - | sym::minimum_number_nsz_f32 - | sym::minimum_number_nsz_f64 - | sym::minimum_number_nsz_f128 + | sym::minimum_number_f16 + | sym::minimum_number_f32 + | sym::minimum_number_f64 + | sym::minimum_number_f128 | sym::minimumf16 | sym::minimumf32 | sym::minimumf64 @@ -468,10 +468,10 @@ pub(crate) fn check_intrinsic_type( sym::fabsf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), sym::fabsf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - sym::minimum_number_nsz_f16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16), - sym::minimum_number_nsz_f32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), - sym::minimum_number_nsz_f64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), - sym::minimum_number_nsz_f128 => { + sym::minimum_number_f16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16), + sym::minimum_number_f32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), + sym::minimum_number_f64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), + sym::minimum_number_f128 => { (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128) } @@ -480,10 +480,10 @@ pub(crate) fn check_intrinsic_type( sym::minimumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), sym::minimumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128), - sym::maximum_number_nsz_f16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16), - sym::maximum_number_nsz_f32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), - sym::maximum_number_nsz_f64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), - sym::maximum_number_nsz_f128 => { + sym::maximum_number_f16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16), + sym::maximum_number_f32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), + sym::maximum_number_f64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), + sym::maximum_number_f128 => { (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128) } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 738c9b975fd00..246c61a143930 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1210,10 +1210,10 @@ symbols! { masked, match_beginning_vert, match_default_bindings, - maximum_number_nsz_f16, - maximum_number_nsz_f32, - maximum_number_nsz_f64, - maximum_number_nsz_f128, + maximum_number_f16, + maximum_number_f32, + maximum_number_f64, + maximum_number_f128, maximumf16, maximumf32, maximumf64, @@ -1248,10 +1248,10 @@ symbols! { min_generic_const_args, min_specialization, min_type_alias_impl_trait, - minimum_number_nsz_f16, - minimum_number_nsz_f32, - minimum_number_nsz_f64, - minimum_number_nsz_f128, + minimum_number_f16, + minimum_number_f32, + minimum_number_f64, + minimum_number_f128, minimumf16, minimumf32, minimumf64, diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 68e4f1c2aa787..5dc8b954ab5f6 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2987,11 +2987,11 @@ pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize); /// Returns the minimum of two `f16` values, ignoring NaN. /// -/// This behaves like IEEE 754-2019 minimumNumber, *except* that it does not order signed +/// This behaves like IEEE 754-2019 minimumNumber, and orders signed /// zeros deterministically. In particular: /// 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. +/// and `-0.0`), the one with the negative sign (for minimum) or positive sign (for maximum) is returned. /// /// Note that, unlike most intrinsics, this is safe to call; /// it does not require an `unsafe` block. @@ -3001,22 +3001,25 @@ pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize); /// The stabilized version of this intrinsic is [`f16::min`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn minimum_number_nsz_f16(x: f16, y: f16) -> f16 { - if x.is_nan() || y <= x { +pub const fn minimum_number_f16(x: f16, y: f16) -> f16 { + if x.is_nan() || y < x { y + } else if x < y { + x + } else if x == y { + if x.is_sign_negative() { x } else { y } } else { - // Either y > x or y is a NaN. x } } /// Returns the minimum of two `f32` values, ignoring NaN. /// -/// This behaves like IEEE 754-2019 minimumNumber, *except* that it does not order signed +/// This behaves like IEEE 754-2019 minimumNumber, and orders signed /// zeros deterministically. In particular: /// 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. +/// and `-0.0`), the one with the negative sign (for minimum) or positive sign (for maximum) is returned. /// /// Note that, unlike most intrinsics, this is safe to call; /// it does not require an `unsafe` block. @@ -3027,22 +3030,25 @@ pub const fn minimum_number_nsz_f16(x: f16, y: f16) -> f16 { #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn minimum_number_nsz_f32(x: f32, y: f32) -> f32 { - if x.is_nan() || y <= x { +pub const fn minimum_number_f32(x: f32, y: f32) -> f32 { + if x.is_nan() || y < x { y + } else if x < y { + x + } else if x == y { + if x.is_sign_negative() { x } else { y } } else { - // Either y > x or y is a NaN. x } } /// Returns the minimum of two `f64` values, ignoring NaN. /// -/// This behaves like IEEE 754-2019 minimumNumber, *except* that it does not order signed +/// This behaves like IEEE 754-2019 minimumNumber, and orders signed /// zeros deterministically. In particular: /// 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. +/// and `-0.0`), the one with the negative sign (for minimum) or positive sign (for maximum) is returned. /// /// Note that, unlike most intrinsics, this is safe to call; /// it does not require an `unsafe` block. @@ -3053,22 +3059,25 @@ pub const fn minimum_number_nsz_f32(x: f32, y: f32) -> f32 { #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn minimum_number_nsz_f64(x: f64, y: f64) -> f64 { - if x.is_nan() || y <= x { +pub const fn minimum_number_f64(x: f64, y: f64) -> f64 { + if x.is_nan() || y < x { y + } else if x < y { + x + } else if x == y { + if x.is_sign_negative() { x } else { y } } else { - // Either y > x or y is a NaN. x } } /// Returns the minimum of two `f128` values, ignoring NaN. /// -/// This behaves like IEEE 754-2019 minimumNumber, *except* that it does not order signed +/// This behaves like IEEE 754-2019 minimumNumber, and orders signed /// zeros deterministically. In particular: /// 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. +/// and `-0.0`), the one with the negative sign (for minimum) or positive sign (for maximum) is returned. /// /// Note that, unlike most intrinsics, this is safe to call; /// it does not require an `unsafe` block. @@ -3078,11 +3087,14 @@ pub const fn minimum_number_nsz_f64(x: f64, y: f64) -> f64 { /// The stabilized version of this intrinsic is [`f128::min`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn minimum_number_nsz_f128(x: f128, y: f128) -> f128 { - if x.is_nan() || y <= x { +pub const fn minimum_number_f128(x: f128, y: f128) -> f128 { + if x.is_nan() || y < x { y + } else if x < y { + x + } else if x == y { + if x.is_sign_negative() { x } else { y } } else { - // Either y > x or y is a NaN. x } } @@ -3189,11 +3201,11 @@ pub const fn minimumf128(x: f128, y: f128) -> f128 { /// Returns the maximum of two `f16` values, ignoring NaN. /// -/// This behaves like IEEE 754-2019 maximumNumber, *except* that it does not order signed +/// This behaves like IEEE 754-2019 maximumNumber, and orders signed /// zeros deterministically. In particular: /// 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. +/// and `-0.0`), the one with the negative sign (for minimum) or positive sign (for maximum) is returned. /// /// Note that, unlike most intrinsics, this is safe to call; /// it does not require an `unsafe` block. @@ -3203,22 +3215,25 @@ pub const fn minimumf128(x: f128, y: f128) -> f128 { /// The stabilized version of this intrinsic is [`f16::max`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn maximum_number_nsz_f16(x: f16, y: f16) -> f16 { - if x.is_nan() || y >= x { +pub const fn maximum_number_f16(x: f16, y: f16) -> f16 { + if x.is_nan() || y > x { y + } else if x > y { + x + } else if x == y { + if x.is_sign_positive() { x } else { y } } else { - // Either y < x or y is a NaN. x } } /// Returns the maximum of two `f32` values, ignoring NaN. /// -/// This behaves like IEEE 754-2019 maximumNumber, *except* that it does not order signed +/// This behaves like IEEE 754-2019 maximumNumber, and orders signed /// zeros deterministically. In particular: /// 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. +/// and `-0.0`), the one with the negative sign (for minimum) or positive sign (for maximum) is returned. /// /// Note that, unlike most intrinsics, this is safe to call; /// it does not require an `unsafe` block. @@ -3229,22 +3244,25 @@ pub const fn maximum_number_nsz_f16(x: f16, y: f16) -> f16 { #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn maximum_number_nsz_f32(x: f32, y: f32) -> f32 { - if x.is_nan() || y >= x { +pub const fn maximum_number_f32(x: f32, y: f32) -> f32 { + if x.is_nan() || y > x { y + } else if x > y { + x + } else if x == y { + if x.is_sign_positive() { x } else { y } } else { - // Either y < x or y is a NaN. x } } /// Returns the maximum of two `f64` values, ignoring NaN. /// -/// This behaves like IEEE 754-2019 maximumNumber, *except* that it does not order signed +/// This behaves like IEEE 754-2019 maximumNumber, and orders signed /// zeros deterministically. In particular: /// 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. +/// and `-0.0`), the one with the negative sign (for minimum) or positive sign (for maximum) is returned. /// /// Note that, unlike most intrinsics, this is safe to call; /// it does not require an `unsafe` block. @@ -3255,22 +3273,25 @@ pub const fn maximum_number_nsz_f32(x: f32, y: f32) -> f32 { #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn maximum_number_nsz_f64(x: f64, y: f64) -> f64 { - if x.is_nan() || y >= x { +pub const fn maximum_number_f64(x: f64, y: f64) -> f64 { + if x.is_nan() || y > x { y + } else if x > y { + x + } else if x == y { + if x.is_sign_positive() { x } else { y } } else { - // Either y < x or y is a NaN. x } } /// Returns the maximum of two `f128` values, ignoring NaN. /// -/// This behaves like IEEE 754-2019 maximumNumber, *except* that it does not order signed +/// This behaves like IEEE 754-2019 maximumNumber, and orders signed /// zeros deterministically. In particular: /// 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. +/// and `-0.0`), the one with the negative sign (for minimum) or positive sign (for maximum) is returned. /// /// Note that, unlike most intrinsics, this is safe to call; /// it does not require an `unsafe` block. @@ -3280,11 +3301,14 @@ pub const fn maximum_number_nsz_f64(x: f64, y: f64) -> f64 { /// The stabilized version of this intrinsic is [`f128::max`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn maximum_number_nsz_f128(x: f128, y: f128) -> f128 { - if x.is_nan() || y >= x { +pub const fn maximum_number_f128(x: f128, y: f128) -> f128 { + if x.is_nan() || y > x { y + } else if x > y { + x + } else if x == y { + if x.is_sign_positive() { x } else { y } } else { - // Either y < x or y is a NaN. x } } diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 68c87b48de94d..f19dcf609ab20 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -790,7 +790,7 @@ impl f128 { #[rustc_const_unstable(feature = "f128", issue = "116909")] #[must_use = "this returns the result of the comparison, without modifying either input"] pub const fn max(self, other: f128) -> f128 { - intrinsics::maximum_number_nsz_f128(self, other) + intrinsics::maximum_number_f128(self, other) } /// Returns the minimum of the two numbers, ignoring NaN. @@ -821,7 +821,7 @@ impl f128 { #[rustc_const_unstable(feature = "f128", issue = "116909")] #[must_use = "this returns the result of the comparison, without modifying either input"] pub const fn min(self, other: f128) -> f128 { - intrinsics::minimum_number_nsz_f128(self, other) + intrinsics::minimum_number_f128(self, other) } /// Returns the maximum of the two numbers, propagating NaN. @@ -1335,7 +1335,7 @@ impl f128 { #[inline] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] - pub const fn clamp(mut self, min: f128, max: f128) -> f128 { + pub const fn clamp(self, min: f128, max: f128) -> f128 { const_assert!( min <= max, "min > max, or either was NaN", @@ -1343,14 +1343,7 @@ impl f128 { min: f128, max: f128, ); - - if self < min { - self = min; - } - if self > max { - self = max; - } - self + self.max(min).min(max) } /// Clamps this number to a symmetric range centered around zero. diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 3412e49c49cd0..dd9db3090f3d8 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -784,7 +784,7 @@ impl f16 { #[rustc_const_unstable(feature = "f16", issue = "116909")] #[must_use = "this returns the result of the comparison, without modifying either input"] pub const fn max(self, other: f16) -> f16 { - intrinsics::maximum_number_nsz_f16(self, other) + intrinsics::maximum_number_f16(self, other) } /// Returns the minimum of the two numbers, ignoring NaN. @@ -815,7 +815,7 @@ impl f16 { #[rustc_const_unstable(feature = "f16", issue = "116909")] #[must_use = "this returns the result of the comparison, without modifying either input"] pub const fn min(self, other: f16) -> f16 { - intrinsics::minimum_number_nsz_f16(self, other) + intrinsics::minimum_number_f16(self, other) } /// Returns the maximum of the two numbers, propagating NaN. @@ -1319,7 +1319,7 @@ impl f16 { #[inline] #[unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] - pub const fn clamp(mut self, min: f16, max: f16) -> f16 { + pub const fn clamp(self, min: f16, max: f16) -> f16 { const_assert!( min <= max, "min > max, or either was NaN", @@ -1327,14 +1327,7 @@ impl f16 { min: f16, max: f16, ); - - if self < min { - self = min; - } - if self > max { - self = max; - } - self + self.max(min).min(max) } /// Clamps this number to a symmetric range centered around zero. diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index e33cb098e4e8d..e7a5d58dce4b6 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -990,7 +990,7 @@ impl f32 { #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn max(self, other: f32) -> f32 { - intrinsics::maximum_number_nsz_f32(self, other) + intrinsics::maximum_number_f32(self, other) } /// Returns the minimum of the two numbers, ignoring NaN. @@ -1017,7 +1017,7 @@ impl f32 { #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn min(self, other: f32) -> f32 { - intrinsics::minimum_number_nsz_f32(self, other) + intrinsics::minimum_number_f32(self, other) } /// Returns the maximum of the two numbers, propagating NaN. @@ -1501,7 +1501,7 @@ impl f32 { #[stable(feature = "clamp", since = "1.50.0")] #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] - pub const fn clamp(mut self, min: f32, max: f32) -> f32 { + pub const fn clamp(self, min: f32, max: f32) -> f32 { const_assert!( min <= max, "min > max, or either was NaN", @@ -1509,14 +1509,7 @@ impl f32 { min: f32, max: f32, ); - - if self < min { - self = min; - } - if self > max { - self = max; - } - self + self.max(min).min(max) } /// Clamps this number to a symmetric range centered around zero. diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 872f567efafdc..233efc0795838 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1008,7 +1008,7 @@ impl f64 { #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn max(self, other: f64) -> f64 { - intrinsics::maximum_number_nsz_f64(self, other) + intrinsics::maximum_number_f64(self, other) } /// Returns the minimum of the two numbers, ignoring NaN. @@ -1035,7 +1035,7 @@ impl f64 { #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn min(self, other: f64) -> f64 { - intrinsics::minimum_number_nsz_f64(self, other) + intrinsics::minimum_number_f64(self, other) } /// Returns the maximum of the two numbers, propagating NaN. @@ -1499,7 +1499,7 @@ impl f64 { #[stable(feature = "clamp", since = "1.50.0")] #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] - pub const fn clamp(mut self, min: f64, max: f64) -> f64 { + pub const fn clamp(self, min: f64, max: f64) -> f64 { const_assert!( min <= max, "min > max, or either was NaN", @@ -1507,14 +1507,7 @@ impl f64 { min: f64, max: f64, ); - - if self < min { - self = min; - } - if self > max { - self = max; - } - self + self.max(min).min(max) } /// Clamps this number to a symmetric range centered around zero.