diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index bf4152d4b8cd5..64467a9013696 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -518,6 +518,103 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { sym::fabsf64 => self.float_abs_intrinsic::(args, dest)?, sym::fabsf128 => self.float_abs_intrinsic::(args, dest)?, + sym::floorf16 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::TowardNegative, + )?, + sym::floorf32 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::TowardNegative, + )?, + sym::floorf64 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::TowardNegative, + )?, + sym::floorf128 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::TowardNegative, + )?, + + sym::ceilf16 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::TowardPositive, + )?, + sym::ceilf32 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::TowardPositive, + )?, + sym::ceilf64 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::TowardPositive, + )?, + sym::ceilf128 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::TowardPositive, + )?, + + sym::truncf16 => { + self.float_round_intrinsic::(args, dest, rustc_apfloat::Round::TowardZero)? + } + sym::truncf32 => { + self.float_round_intrinsic::(args, dest, rustc_apfloat::Round::TowardZero)? + } + sym::truncf64 => { + self.float_round_intrinsic::(args, dest, rustc_apfloat::Round::TowardZero)? + } + sym::truncf128 => { + self.float_round_intrinsic::(args, dest, rustc_apfloat::Round::TowardZero)? + } + + sym::roundf16 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::NearestTiesToAway, + )?, + sym::roundf32 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::NearestTiesToAway, + )?, + sym::roundf64 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::NearestTiesToAway, + )?, + sym::roundf128 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::NearestTiesToAway, + )?, + + sym::round_ties_even_f16 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::NearestTiesToEven, + )?, + sym::round_ties_even_f32 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::NearestTiesToEven, + )?, + sym::round_ties_even_f64 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::NearestTiesToEven, + )?, + sym::round_ties_even_f128 => self.float_round_intrinsic::( + args, + dest, + rustc_apfloat::Round::NearestTiesToEven, + )?, + // Unsupported intrinsic: skip the return_to_block below. _ => return interp_ok(false), } @@ -900,4 +997,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_scalar(x.abs(), dest)?; interp_ok(()) } + + fn float_round_intrinsic( + &mut self, + args: &[OpTy<'tcx, M::Provenance>], + dest: &PlaceTy<'tcx, M::Provenance>, + mode: rustc_apfloat::Round, + ) -> InterpResult<'tcx, ()> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + let x: F = self.read_scalar(&args[0])?.to_float()?; + let res = x.round_to_integral(mode).value; + let res = self.adjust_nan(res, &[x]); + self.write_scalar(res, dest)?; + interp_ok(()) + } } diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index f4dba79666a6d..29efb806ee16b 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2186,28 +2186,28 @@ pub unsafe fn fmuladdf128(a: f128, b: f128, c: f128) -> f128; /// [`f16::floor`](../../std/primitive.f16.html#method.floor) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn floorf16(x: f16) -> f16; +pub const unsafe fn floorf16(x: f16) -> f16; /// Returns the largest integer less than or equal to an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::floor`](../../std/primitive.f32.html#method.floor) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn floorf32(x: f32) -> f32; +pub const unsafe fn floorf32(x: f32) -> f32; /// Returns the largest integer less than or equal to an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::floor`](../../std/primitive.f64.html#method.floor) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn floorf64(x: f64) -> f64; +pub const unsafe fn floorf64(x: f64) -> f64; /// Returns the largest integer less than or equal to an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::floor`](../../std/primitive.f128.html#method.floor) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn floorf128(x: f128) -> f128; +pub const unsafe fn floorf128(x: f128) -> f128; /// Returns the smallest integer greater than or equal to an `f16`. /// @@ -2215,28 +2215,28 @@ pub unsafe fn floorf128(x: f128) -> f128; /// [`f16::ceil`](../../std/primitive.f16.html#method.ceil) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn ceilf16(x: f16) -> f16; +pub const unsafe fn ceilf16(x: f16) -> f16; /// Returns the smallest integer greater than or equal to an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::ceil`](../../std/primitive.f32.html#method.ceil) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn ceilf32(x: f32) -> f32; +pub const unsafe fn ceilf32(x: f32) -> f32; /// Returns the smallest integer greater than or equal to an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::ceil`](../../std/primitive.f64.html#method.ceil) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn ceilf64(x: f64) -> f64; +pub const unsafe fn ceilf64(x: f64) -> f64; /// Returns the smallest integer greater than or equal to an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::ceil`](../../std/primitive.f128.html#method.ceil) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn ceilf128(x: f128) -> f128; +pub const unsafe fn ceilf128(x: f128) -> f128; /// Returns the integer part of an `f16`. /// @@ -2244,28 +2244,28 @@ pub unsafe fn ceilf128(x: f128) -> f128; /// [`f16::trunc`](../../std/primitive.f16.html#method.trunc) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn truncf16(x: f16) -> f16; +pub const unsafe fn truncf16(x: f16) -> f16; /// Returns the integer part of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::trunc`](../../std/primitive.f32.html#method.trunc) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn truncf32(x: f32) -> f32; +pub const unsafe fn truncf32(x: f32) -> f32; /// Returns the integer part of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::trunc`](../../std/primitive.f64.html#method.trunc) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn truncf64(x: f64) -> f64; +pub const unsafe fn truncf64(x: f64) -> f64; /// Returns the integer part of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::trunc`](../../std/primitive.f128.html#method.trunc) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn truncf128(x: f128) -> f128; +pub const unsafe fn truncf128(x: f128) -> f128; /// Returns the nearest integer to an `f16`. Rounds half-way cases to the number with an even /// least significant digit. @@ -2274,7 +2274,7 @@ pub unsafe fn truncf128(x: f128) -> f128; /// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even) #[rustc_intrinsic] #[rustc_nounwind] -pub fn round_ties_even_f16(x: f16) -> f16; +pub const fn round_ties_even_f16(x: f16) -> f16; /// Returns the nearest integer to an `f32`. Rounds half-way cases to the number with an even /// least significant digit. @@ -2283,7 +2283,7 @@ pub fn round_ties_even_f16(x: f16) -> f16; /// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even) #[rustc_intrinsic] #[rustc_nounwind] -pub fn round_ties_even_f32(x: f32) -> f32; +pub const fn round_ties_even_f32(x: f32) -> f32; /// Returns the nearest integer to an `f64`. Rounds half-way cases to the number with an even /// least significant digit. @@ -2292,7 +2292,7 @@ pub fn round_ties_even_f32(x: f32) -> f32; /// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even) #[rustc_intrinsic] #[rustc_nounwind] -pub fn round_ties_even_f64(x: f64) -> f64; +pub const fn round_ties_even_f64(x: f64) -> f64; /// Returns the nearest integer to an `f128`. Rounds half-way cases to the number with an even /// least significant digit. @@ -2301,7 +2301,7 @@ pub fn round_ties_even_f64(x: f64) -> f64; /// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even) #[rustc_intrinsic] #[rustc_nounwind] -pub fn round_ties_even_f128(x: f128) -> f128; +pub const fn round_ties_even_f128(x: f128) -> f128; /// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero. /// @@ -2309,28 +2309,28 @@ pub fn round_ties_even_f128(x: f128) -> f128; /// [`f16::round`](../../std/primitive.f16.html#method.round) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn roundf16(x: f16) -> f16; +pub const unsafe fn roundf16(x: f16) -> f16; /// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero. /// /// The stabilized version of this intrinsic is /// [`f32::round`](../../std/primitive.f32.html#method.round) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn roundf32(x: f32) -> f32; +pub const unsafe fn roundf32(x: f32) -> f32; /// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero. /// /// The stabilized version of this intrinsic is /// [`f64::round`](../../std/primitive.f64.html#method.round) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn roundf64(x: f64) -> f64; +pub const unsafe fn roundf64(x: f64) -> f64; /// Returns the nearest integer to an `f128`. Rounds half-way cases away from zero. /// /// The stabilized version of this intrinsic is /// [`f128::round`](../../std/primitive.f128.html#method.round) #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn roundf128(x: f128) -> f128; +pub const unsafe fn roundf128(x: f128) -> f128; /// Float addition that allows optimizations based on algebraic rules. /// May assume inputs are finite. diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 0c2c4155d66ce..bc1c6a7f7f163 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1447,8 +1447,10 @@ impl f128 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn floor(self) -> f128 { + pub const fn floor(self) -> f128 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::floorf128(self) } } @@ -1477,8 +1479,10 @@ impl f128 { #[doc(alias = "ceiling")] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn ceil(self) -> f128 { + pub const fn ceil(self) -> f128 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::ceilf128(self) } } @@ -1513,8 +1517,10 @@ impl f128 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn round(self) -> f128 { + pub const fn round(self) -> f128 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::roundf128(self) } } @@ -1547,8 +1553,10 @@ impl f128 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn round_ties_even(self) -> f128 { + pub const fn round_ties_even(self) -> f128 { intrinsics::round_ties_even_f128(self) } @@ -1579,8 +1587,10 @@ impl f128 { #[doc(alias = "truncate")] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn trunc(self) -> f128 { + pub const fn trunc(self) -> f128 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::truncf128(self) } } @@ -1610,8 +1620,10 @@ impl f128 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn fract(self) -> f128 { + pub const fn fract(self) -> f128 { self - self.trunc() } @@ -1697,8 +1709,9 @@ impl f128 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_euclidean_division", issue = "141572")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn div_euclid(self, rhs: f128) -> f128 { + pub const fn div_euclid(self, rhs: f128) -> f128 { let q = (self / rhs).trunc(); if self % rhs < 0.0 { return if rhs > 0.0 { q - 1.0 } else { q + 1.0 }; @@ -1746,7 +1759,8 @@ impl f128 { #[doc(alias = "modulo", alias = "mod")] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn rem_euclid(self, rhs: f128) -> f128 { + #[rustc_const_unstable(feature = "const_float_euclidean_division", issue = "141572")] + pub const fn rem_euclid(self, rhs: f128) -> f128 { let r = self % rhs; if r < 0.0 { r + rhs.abs() } else { r } } diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 1a859f2277ff3..dd270d91bc1dc 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1423,8 +1423,10 @@ impl f16 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn floor(self) -> f16 { + pub const fn floor(self) -> f16 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::floorf16(self) } } @@ -1453,8 +1455,10 @@ impl f16 { #[doc(alias = "ceiling")] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn ceil(self) -> f16 { + pub const fn ceil(self) -> f16 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::ceilf16(self) } } @@ -1489,8 +1493,10 @@ impl f16 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn round(self) -> f16 { + pub const fn round(self) -> f16 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::roundf16(self) } } @@ -1523,8 +1529,10 @@ impl f16 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn round_ties_even(self) -> f16 { + pub const fn round_ties_even(self) -> f16 { intrinsics::round_ties_even_f16(self) } @@ -1555,8 +1563,10 @@ impl f16 { #[doc(alias = "truncate")] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn trunc(self) -> f16 { + pub const fn trunc(self) -> f16 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::truncf16(self) } } @@ -1586,8 +1596,10 @@ impl f16 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] + // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn fract(self) -> f16 { + pub const fn fract(self) -> f16 { self - self.trunc() } @@ -1673,8 +1685,9 @@ impl f16 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_euclidean_division", issue = "141572")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn div_euclid(self, rhs: f16) -> f16 { + pub const fn div_euclid(self, rhs: f16) -> f16 { let q = (self / rhs).trunc(); if self % rhs < 0.0 { return if rhs > 0.0 { q - 1.0 } else { q + 1.0 }; @@ -1721,8 +1734,9 @@ impl f16 { #[rustc_allow_incoherent_impl] #[doc(alias = "modulo", alias = "mod")] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_euclidean_division", issue = "141572")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn rem_euclid(self, rhs: f16) -> f16 { + pub const fn rem_euclid(self, rhs: f16) -> f16 { let r = self % rhs; if r < 0.0 { r + rhs.abs() } else { r } } diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index bf67b6ed05afb..008331892ad8c 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1590,8 +1590,9 @@ pub mod math { /// [`f32::floor`]: ../../../std/primitive.f32.html#method.floor #[inline] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn floor(x: f32) -> f32 { + pub const fn floor(x: f32) -> f32 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::floorf32(x) } } @@ -1620,7 +1621,8 @@ pub mod math { #[doc(alias = "ceiling")] #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "core_float_math", issue = "137578")] - pub fn ceil(x: f32) -> f32 { + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] + pub const fn ceil(x: f32) -> f32 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::ceilf32(x) } } @@ -1654,7 +1656,8 @@ pub mod math { #[inline] #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn round(x: f32) -> f32 { + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] + pub const fn round(x: f32) -> f32 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::roundf32(x) } } @@ -1687,7 +1690,8 @@ pub mod math { #[inline] #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn round_ties_even(x: f32) -> f32 { + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] + pub const fn round_ties_even(x: f32) -> f32 { intrinsics::round_ties_even_f32(x) } @@ -1717,7 +1721,8 @@ pub mod math { #[doc(alias = "truncate")] #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "core_float_math", issue = "137578")] - pub fn trunc(x: f32) -> f32 { + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] + pub const fn trunc(x: f32) -> f32 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::truncf32(x) } } @@ -1746,8 +1751,9 @@ pub mod math { /// [`f32::fract`]: ../../../std/primitive.f32.html#method.fract #[inline] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn fract(x: f32) -> f32 { + pub const fn fract(x: f32) -> f32 { x - trunc(x) } @@ -1820,8 +1826,9 @@ pub mod math { /// [`f32::div_euclid`]: ../../../std/primitive.f32.html#method.div_euclid #[inline] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_euclidean_division", issue = "141572")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn div_euclid(x: f32, rhs: f32) -> f32 { + pub const fn div_euclid(x: f32, rhs: f32) -> f32 { let q = trunc(x / rhs); if x % rhs < 0.0 { return if rhs > 0.0 { q - 1.0 } else { q + 1.0 }; @@ -1856,7 +1863,7 @@ pub mod math { #[doc(alias = "modulo", alias = "mod")] #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn rem_euclid(x: f32, rhs: f32) -> f32 { + pub const fn rem_euclid(x: f32, rhs: f32) -> f32 { let r = x % rhs; if r < 0.0 { r + rhs.abs() } else { r } } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 8fbf2cffbaf4e..2c7cf5e69dd37 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1589,8 +1589,9 @@ pub mod math { /// [`f64::floor`]: ../../../std/primitive.f64.html#method.floor #[inline] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn floor(x: f64) -> f64 { + pub const fn floor(x: f64) -> f64 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::floorf64(x) } } @@ -1618,8 +1619,9 @@ pub mod math { #[inline] #[doc(alias = "ceiling")] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn ceil(x: f64) -> f64 { + pub const fn ceil(x: f64) -> f64 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::ceilf64(x) } } @@ -1652,8 +1654,9 @@ pub mod math { /// [`f64::round`]: ../../../std/primitive.f64.html#method.round #[inline] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn round(x: f64) -> f64 { + pub const fn round(x: f64) -> f64 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::roundf64(x) } } @@ -1685,8 +1688,9 @@ pub mod math { /// [`f64::round_ties_even`]: ../../../std/primitive.f64.html#method.round_ties_even #[inline] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn round_ties_even(x: f64) -> f64 { + pub const fn round_ties_even(x: f64) -> f64 { intrinsics::round_ties_even_f64(x) } @@ -1715,8 +1719,9 @@ pub mod math { #[inline] #[doc(alias = "truncate")] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn trunc(x: f64) -> f64 { + pub const fn trunc(x: f64) -> f64 { // SAFETY: intrinsic with no preconditions unsafe { intrinsics::truncf64(x) } } @@ -1745,8 +1750,9 @@ pub mod math { /// [`f64::fract`]: ../../../std/primitive.f64.html#method.fract #[inline] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn fract(x: f64) -> f64 { + pub const fn fract(x: f64) -> f64 { x - trunc(x) } @@ -1819,8 +1825,9 @@ pub mod math { /// [`f64::div_euclid`]: ../../../std/primitive.f64.html#method.div_euclid #[inline] #[unstable(feature = "core_float_math", issue = "137578")] + #[rustc_const_unstable(feature = "const_float_euclidean_division", issue = "141572")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn div_euclid(x: f64, rhs: f64) -> f64 { + pub const fn div_euclid(x: f64, rhs: f64) -> f64 { let q = trunc(x / rhs); if x % rhs < 0.0 { return if rhs > 0.0 { q - 1.0 } else { q + 1.0 }; @@ -1855,7 +1862,7 @@ pub mod math { #[doc(alias = "modulo", alias = "mod")] #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn rem_euclid(x: f64, rhs: f64) -> f64 { + pub const fn rem_euclid(x: f64, rhs: f64) -> f64 { let r = x % rhs; if r < 0.0 { r + rhs.abs() } else { r } } diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 693b14ef76209..e74adeb1687aa 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -16,6 +16,8 @@ #![feature(char_max_len)] #![feature(clone_to_uninit)] #![feature(const_eval_select)] +#![feature(const_float_euclidean_division)] +#![feature(const_float_round_methods)] #![feature(const_trait_impl)] #![feature(core_float_math)] #![feature(core_intrinsics)] diff --git a/library/coretests/tests/num/mod.rs b/library/coretests/tests/num/mod.rs index 1212d36a1b15c..e78d7cd7d1368 100644 --- a/library/coretests/tests/num/mod.rs +++ b/library/coretests/tests/num/mod.rs @@ -731,6 +731,9 @@ assume_usize_width! { } } +// FIXME(141726): there is a lot of duplication between the following tests and +// the tests in `coretests/tests/floats/f*.rs` +// See issue https://github.com/rust-lang/rust/issues/141726 for more details. macro_rules! test_float { ($modname: ident, $fassert: ident, $fty: ty) => { mod $modname { @@ -929,23 +932,134 @@ macro_rules! test_float { $fassert!(<$fty>::NEG_INFINITY.copysign(0.0), <$fty>::INFINITY); } #[test] + #[cfg(not(bootstrap))] fn rem_euclid() { - // FIXME: Use $fassert when rem_euclid becomes const - assert!(<$fty>::INFINITY.rem_euclid((42.0 as $fty)).is_nan()); - assert_eq!((42.0 as $fty).rem_euclid(<$fty>::INFINITY), (42.0 as $fty)); - assert!((42.0 as $fty).rem_euclid(<$fty>::NAN).is_nan()); - assert!(<$fty>::INFINITY.rem_euclid(<$fty>::INFINITY).is_nan()); - assert!(<$fty>::INFINITY.rem_euclid(<$fty>::NAN).is_nan()); - assert!(<$fty>::NAN.rem_euclid(<$fty>::INFINITY).is_nan()); + $fassert!(<$fty>::INFINITY.rem_euclid((42.0 as $fty)).is_nan()); + $fassert!((42.0 as $fty).rem_euclid(<$fty>::INFINITY), (42.0 as $fty)); + $fassert!((42.0 as $fty).rem_euclid(<$fty>::NAN).is_nan()); + $fassert!(<$fty>::INFINITY.rem_euclid(<$fty>::INFINITY).is_nan()); + $fassert!(<$fty>::INFINITY.rem_euclid(<$fty>::NAN).is_nan()); + $fassert!(<$fty>::NAN.rem_euclid(<$fty>::INFINITY).is_nan()); } #[test] + #[cfg(not(bootstrap))] fn div_euclid() { - // FIXME: Use $fassert when div_euclid becomes const - assert_eq!((42.0 as $fty).div_euclid(<$fty>::INFINITY), 0.0); - assert!((42.0 as $fty).div_euclid(<$fty>::NAN).is_nan()); - assert!(<$fty>::INFINITY.div_euclid(<$fty>::INFINITY).is_nan()); - assert!(<$fty>::INFINITY.div_euclid(<$fty>::NAN).is_nan()); - assert!(<$fty>::NAN.div_euclid(<$fty>::INFINITY).is_nan()); + $fassert!((42.0 as $fty).div_euclid(<$fty>::INFINITY), 0.0); + $fassert!((42.0 as $fty).div_euclid(<$fty>::NAN).is_nan()); + $fassert!(<$fty>::INFINITY.div_euclid(<$fty>::INFINITY).is_nan()); + $fassert!(<$fty>::INFINITY.div_euclid(<$fty>::NAN).is_nan()); + $fassert!(<$fty>::NAN.div_euclid(<$fty>::INFINITY).is_nan()); + } + #[test] + #[cfg(not(bootstrap))] + fn floor() { + $fassert!((0.0 as $fty).floor(), 0.0); + $fassert!((0.0 as $fty).floor().is_sign_positive()); + $fassert!((-0.0 as $fty).floor(), -0.0); + $fassert!((-0.0 as $fty).floor().is_sign_negative()); + $fassert!((0.5 as $fty).floor(), 0.0); + $fassert!((-0.5 as $fty).floor(), -1.0); + $fassert!((1.5 as $fty).floor(), 1.0); + $fassert!(<$fty>::MAX.floor(), <$fty>::MAX); + $fassert!(<$fty>::MIN.floor(), <$fty>::MIN); + $fassert!(<$fty>::MIN_POSITIVE.floor(), 0.0); + $fassert!((-<$fty>::MIN_POSITIVE).floor(), -1.0); + $fassert!(<$fty>::NAN.floor().is_nan()); + $fassert!(<$fty>::INFINITY.floor(), <$fty>::INFINITY); + $fassert!(<$fty>::NEG_INFINITY.floor(), <$fty>::NEG_INFINITY); + } + #[test] + #[cfg(not(bootstrap))] + fn ceil() { + $fassert!((0.0 as $fty).ceil(), 0.0); + $fassert!((0.0 as $fty).ceil().is_sign_positive()); + $fassert!((-0.0 as $fty).ceil(), 0.0); + $fassert!((-0.0 as $fty).ceil().is_sign_negative()); + $fassert!((0.5 as $fty).ceil(), 1.0); + $fassert!((-0.5 as $fty).ceil(), 0.0); + $fassert!(<$fty>::MAX.ceil(), <$fty>::MAX); + $fassert!(<$fty>::MIN.ceil(), <$fty>::MIN); + $fassert!(<$fty>::MIN_POSITIVE.ceil(), 1.0); + $fassert!((-<$fty>::MIN_POSITIVE).ceil(), 0.0); + $fassert!(<$fty>::NAN.ceil().is_nan()); + $fassert!(<$fty>::INFINITY.ceil(), <$fty>::INFINITY); + $fassert!(<$fty>::NEG_INFINITY.ceil(), <$fty>::NEG_INFINITY); + } + #[test] + #[cfg(not(bootstrap))] + fn round() { + $fassert!((0.0 as $fty).round(), 0.0); + $fassert!((0.0 as $fty).round().is_sign_positive()); + $fassert!((-0.0 as $fty).round(), -0.0); + $fassert!((-0.0 as $fty).round().is_sign_negative()); + $fassert!((0.5 as $fty).round(), 1.0); + $fassert!((-0.5 as $fty).round(), -1.0); + $fassert!(<$fty>::MAX.round(), <$fty>::MAX); + $fassert!(<$fty>::MIN.round(), <$fty>::MIN); + $fassert!(<$fty>::MIN_POSITIVE.round(), 0.0); + $fassert!((-<$fty>::MIN_POSITIVE).round(), 0.0); + $fassert!(<$fty>::NAN.round().is_nan()); + $fassert!(<$fty>::INFINITY.round(), <$fty>::INFINITY); + $fassert!(<$fty>::NEG_INFINITY.round(), <$fty>::NEG_INFINITY); + } + #[test] + #[cfg(not(bootstrap))] + fn round_ties_even() { + $fassert!((0.0 as $fty).round_ties_even(), 0.0); + $fassert!((0.0 as $fty).round_ties_even().is_sign_positive()); + $fassert!((-0.0 as $fty).round_ties_even(), -0.0); + $fassert!((-0.0 as $fty).round_ties_even().is_sign_negative()); + $fassert!((0.5 as $fty).round_ties_even(), 0.0); + $fassert!((0.5 as $fty).round_ties_even().is_sign_positive()); + $fassert!((-0.5 as $fty).round_ties_even(), -0.0); + $fassert!((-0.5 as $fty).round_ties_even().is_sign_negative()); + $fassert!(<$fty>::MAX.round_ties_even(), <$fty>::MAX); + $fassert!(<$fty>::MIN.round_ties_even(), <$fty>::MIN); + $fassert!(<$fty>::MIN_POSITIVE.round_ties_even(), 0.0); + $fassert!((-<$fty>::MIN_POSITIVE).round_ties_even(), 0.0); + $fassert!(<$fty>::NAN.round_ties_even().is_nan()); + $fassert!(<$fty>::INFINITY.round_ties_even(), <$fty>::INFINITY); + $fassert!(<$fty>::NEG_INFINITY.round_ties_even(), <$fty>::NEG_INFINITY); + } + #[test] + #[cfg(not(bootstrap))] + fn trunc() { + $fassert!((0.0 as $fty).trunc(), 0.0); + $fassert!((0.0 as $fty).trunc().is_sign_positive()); + $fassert!((-0.0 as $fty).trunc(), -0.0); + $fassert!((-0.0 as $fty).trunc().is_sign_negative()); + $fassert!((0.5 as $fty).trunc(), 0.0); + $fassert!((0.5 as $fty).trunc().is_sign_positive()); + $fassert!((-0.5 as $fty).trunc(), -0.0); + $fassert!((-0.5 as $fty).trunc().is_sign_negative()); + $fassert!(<$fty>::MAX.trunc(), <$fty>::MAX); + $fassert!(<$fty>::MIN.trunc(), <$fty>::MIN); + $fassert!(<$fty>::MIN_POSITIVE.trunc(), 0.0); + $fassert!((-<$fty>::MIN_POSITIVE).trunc(), 0.0); + $fassert!(<$fty>::NAN.trunc().is_nan()); + $fassert!(<$fty>::INFINITY.trunc(), <$fty>::INFINITY); + $fassert!(<$fty>::NEG_INFINITY.trunc(), <$fty>::NEG_INFINITY); + } + #[test] + #[cfg(not(bootstrap))] + fn fract() { + $fassert!((0.0 as $fty).fract(), 0.0); + $fassert!((0.0 as $fty).fract().is_sign_positive()); + $fassert!((-0.0 as $fty).fract(), 0.0); + $fassert!((-0.0 as $fty).fract().is_sign_positive()); + $fassert!((0.5 as $fty).fract(), 0.5); + $fassert!((0.5 as $fty).fract().is_sign_positive()); + $fassert!((-0.5 as $fty).fract(), -0.5); + $fassert!((-0.5 as $fty).fract().is_sign_negative()); + $fassert!(<$fty>::MAX.fract(), 0.0); + $fassert!(<$fty>::MIN.fract(), 0.0); + $fassert!(<$fty>::MIN_POSITIVE.fract(), <$fty>::MIN_POSITIVE); + $fassert!(<$fty>::MIN_POSITIVE.fract().is_sign_positive()); + $fassert!((-<$fty>::MIN_POSITIVE).fract(), -<$fty>::MIN_POSITIVE); + $fassert!((-<$fty>::MIN_POSITIVE).fract().is_sign_negative()); + $fassert!(<$fty>::NAN.fract().is_nan()); + $fassert!(<$fty>::INFINITY.fract().is_nan()); + $fassert!(<$fty>::NEG_INFINITY.fract().is_nan()); } } }; @@ -971,7 +1085,13 @@ macro_rules! float_const_assert { }; } +#[cfg(any(miri, target_has_reliable_f16_math))] +test_float!(f16, float_assert, f16); +test_float!(f16_const, float_const_assert, f16); test_float!(f32, float_assert, f32); test_float!(f32_const, float_const_assert, f32); test_float!(f64, float_assert, f64); test_float!(f64_const, float_const_assert, f64); +#[cfg(any(miri, target_has_reliable_f128_math))] +test_float!(f128, float_assert, f128); +test_float!(f128_const, float_const_assert, f128); diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index 5210e75ec4531..ea96e63fbe75c 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -44,8 +44,9 @@ impl f32 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn floor(self) -> f32 { + pub const fn floor(self) -> f32 { core::f32::math::floor(self) } @@ -66,8 +67,9 @@ impl f32 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn ceil(self) -> f32 { + pub const fn ceil(self) -> f32 { core::f32::math::ceil(self) } @@ -94,8 +96,9 @@ impl f32 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn round(self) -> f32 { + pub const fn round(self) -> f32 { core::f32::math::round(self) } @@ -120,8 +123,9 @@ impl f32 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "round_ties_even", since = "1.77.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn round_ties_even(self) -> f32 { + pub const fn round_ties_even(self) -> f32 { core::f32::math::round_ties_even(self) } @@ -145,8 +149,9 @@ impl f32 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn trunc(self) -> f32 { + pub const fn trunc(self) -> f32 { core::f32::math::trunc(self) } @@ -168,8 +173,9 @@ impl f32 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn fract(self) -> f32 { + pub const fn fract(self) -> f32 { core::f32::math::fract(self) } @@ -241,7 +247,8 @@ impl f32 { #[must_use = "method returns a new number and does not mutate the original value"] #[inline] #[stable(feature = "euclidean_division", since = "1.38.0")] - pub fn div_euclid(self, rhs: f32) -> f32 { + #[rustc_const_unstable(feature = "const_float_euclidean_division", issue = "141572")] + pub const fn div_euclid(self, rhs: f32) -> f32 { core::f32::math::div_euclid(self, rhs) } @@ -278,7 +285,8 @@ impl f32 { #[must_use = "method returns a new number and does not mutate the original value"] #[inline] #[stable(feature = "euclidean_division", since = "1.38.0")] - pub fn rem_euclid(self, rhs: f32) -> f32 { + #[rustc_const_unstable(feature = "const_float_euclidean_division", issue = "141572")] + pub const fn rem_euclid(self, rhs: f32) -> f32 { core::f32::math::rem_euclid(self, rhs) } diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index f837800d66342..2d4e96d111110 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -44,8 +44,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn floor(self) -> f64 { + pub const fn floor(self) -> f64 { core::f64::math::floor(self) } @@ -66,8 +67,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn ceil(self) -> f64 { + pub const fn ceil(self) -> f64 { core::f64::math::ceil(self) } @@ -94,8 +96,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn round(self) -> f64 { + pub const fn round(self) -> f64 { core::f64::math::round(self) } @@ -120,8 +123,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "round_ties_even", since = "1.77.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn round_ties_even(self) -> f64 { + pub const fn round_ties_even(self) -> f64 { core::f64::math::round_ties_even(self) } @@ -145,8 +149,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn trunc(self) -> f64 { + pub const fn trunc(self) -> f64 { core::f64::math::trunc(self) } @@ -168,8 +173,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")] #[inline] - pub fn fract(self) -> f64 { + pub const fn fract(self) -> f64 { core::f64::math::fract(self) } @@ -241,7 +247,8 @@ impl f64 { #[must_use = "method returns a new number and does not mutate the original value"] #[inline] #[stable(feature = "euclidean_division", since = "1.38.0")] - pub fn div_euclid(self, rhs: f64) -> f64 { + #[rustc_const_unstable(feature = "const_float_euclidean_division", issue = "141572")] + pub const fn div_euclid(self, rhs: f64) -> f64 { core::f64::math::div_euclid(self, rhs) } @@ -278,7 +285,8 @@ impl f64 { #[must_use = "method returns a new number and does not mutate the original value"] #[inline] #[stable(feature = "euclidean_division", since = "1.38.0")] - pub fn rem_euclid(self, rhs: f64) -> f64 { + #[rustc_const_unstable(feature = "const_float_euclidean_division", issue = "141572")] + pub const fn rem_euclid(self, rhs: f64) -> f64 { core::f64::math::rem_euclid(self, rhs) } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 4b2418a498581..c7c8ca4d74051 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -335,6 +335,8 @@ #![feature(bstr_internals)] #![feature(char_internals)] #![feature(clone_to_uninit)] +#![feature(const_float_euclidean_division)] +#![feature(const_float_round_methods)] #![feature(core_intrinsics)] #![feature(core_io_borrowed_buf)] #![feature(duration_constants)] diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index 69baa472cd694..52317bdd5980a 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -159,67 +159,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_bool(branch), dest)?; } - "floorf16" | "ceilf16" | "truncf16" | "roundf16" | "round_ties_even_f16" => { - let [f] = check_intrinsic_arg_count(args)?; - let f = this.read_scalar(f)?.to_f16()?; - let mode = match intrinsic_name { - "floorf16" => Round::TowardNegative, - "ceilf16" => Round::TowardPositive, - "truncf16" => Round::TowardZero, - "roundf16" => Round::NearestTiesToAway, - "round_ties_even_f16" => Round::NearestTiesToEven, - _ => bug!(), - }; - let res = f.round_to_integral(mode).value; - let res = this.adjust_nan(res, &[f]); - this.write_scalar(res, dest)?; - } - "floorf32" | "ceilf32" | "truncf32" | "roundf32" | "round_ties_even_f32" => { - let [f] = check_intrinsic_arg_count(args)?; - let f = this.read_scalar(f)?.to_f32()?; - let mode = match intrinsic_name { - "floorf32" => Round::TowardNegative, - "ceilf32" => Round::TowardPositive, - "truncf32" => Round::TowardZero, - "roundf32" => Round::NearestTiesToAway, - "round_ties_even_f32" => Round::NearestTiesToEven, - _ => bug!(), - }; - let res = f.round_to_integral(mode).value; - let res = this.adjust_nan(res, &[f]); - this.write_scalar(res, dest)?; - } - "floorf64" | "ceilf64" | "truncf64" | "roundf64" | "round_ties_even_f64" => { - let [f] = check_intrinsic_arg_count(args)?; - let f = this.read_scalar(f)?.to_f64()?; - let mode = match intrinsic_name { - "floorf64" => Round::TowardNegative, - "ceilf64" => Round::TowardPositive, - "truncf64" => Round::TowardZero, - "roundf64" => Round::NearestTiesToAway, - "round_ties_even_f64" => Round::NearestTiesToEven, - _ => bug!(), - }; - let res = f.round_to_integral(mode).value; - let res = this.adjust_nan(res, &[f]); - this.write_scalar(res, dest)?; - } - "floorf128" | "ceilf128" | "truncf128" | "roundf128" | "round_ties_even_f128" => { - let [f] = check_intrinsic_arg_count(args)?; - let f = this.read_scalar(f)?.to_f128()?; - let mode = match intrinsic_name { - "floorf128" => Round::TowardNegative, - "ceilf128" => Round::TowardPositive, - "truncf128" => Round::TowardZero, - "roundf128" => Round::NearestTiesToAway, - "round_ties_even_f128" => Round::NearestTiesToEven, - _ => bug!(), - }; - let res = f.round_to_integral(mode).value; - let res = this.adjust_nan(res, &[f]); - this.write_scalar(res, dest)?; - } - "sqrtf32" => { let [f] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f32()?;