about summary refs log tree commit diff
path: root/library/core
diff options
context:
space:
mode:
authorTrevor Gross <t.gross35@gmail.com>2025-02-23 14:30:25 -0500
committerGitHub <noreply@github.com>2025-02-23 14:30:25 -0500
commita2bb4d748db15454900f5830cfc6ab1c7311ea8b (patch)
tree8de549d2a4c71a53a6a5e9bc96216c4a657b3b12 /library/core
parent31719b59c87272e956e0855bf96e7f9239f46150 (diff)
parentb9d0555d11736f96b4fbbb83bfed94a7098a9ba7 (diff)
downloadrust-a2bb4d748db15454900f5830cfc6ab1c7311ea8b.tar.gz
rust-a2bb4d748db15454900f5830cfc6ab1c7311ea8b.zip
Rollup merge of #136543 - RalfJung:round-ties-even, r=tgross35
intrinsics: unify rint, roundeven, nearbyint in a single round_ties_even intrinsic

LLVM has three intrinsics here that all do the same thing (when used in the default FP environment). There's no reason Rust needs to copy that historically-grown mess -- let's just have one intrinsic and leave it up to the LLVM backend to decide how to lower that.

Suggested by `@hanna-kruppe` in https://github.com/rust-lang/rust/issues/136459; Cc `@tgross35`

try-job: test-various
Diffstat (limited to 'library/core')
-rw-r--r--library/core/src/intrinsics/mod.rs197
1 files changed, 85 insertions, 112 deletions
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index e2ab9be2bd2..ae2b3b92b82 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -2731,110 +2731,124 @@ pub unsafe fn truncf128(_x: f128) -> f128 {
     unreachable!()
 }
 
-/// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust,
-/// so this rounds half-way cases to the number with an even least significant digit.
-///
-/// May raise an inexact floating-point exception if the argument is not an integer.
-/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
-/// cannot actually be utilized from Rust code.
-/// In other words, this intrinsic is equivalent in behavior to `nearbyintf16` and `roundevenf16`.
+/// Returns the nearest integer to an `f16`. Rounds half-way cases to the number with an even
+/// least significant digit.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even)
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 #[rustc_nounwind]
-pub unsafe fn rintf16(_x: f16) -> f16 {
+#[cfg(not(bootstrap))]
+pub fn round_ties_even_f16(_x: f16) -> f16 {
     unreachable!()
 }
-/// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust,
-/// so this rounds half-way cases to the number with an even least significant digit.
-///
-/// May raise an inexact floating-point exception if the argument is not an integer.
-/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
-/// cannot actually be utilized from Rust code.
-/// In other words, this intrinsic is equivalent in behavior to `nearbyintf32` and `roundevenf32`.
+
+/// To be removed on next bootstrap bump.
+#[cfg(bootstrap)]
+pub fn round_ties_even_f16(x: f16) -> f16 {
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    #[rustc_nounwind]
+    unsafe fn rintf16(_x: f16) -> f16 {
+        unreachable!()
+    }
+
+    // SAFETY: this intrinsic isn't actually unsafe
+    unsafe { rintf16(x) }
+}
+
+/// Returns the nearest integer to an `f32`. Rounds half-way cases to the number with an even
+/// least significant digit.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even)
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 #[rustc_nounwind]
-pub unsafe fn rintf32(_x: f32) -> f32 {
+#[cfg(not(bootstrap))]
+pub fn round_ties_even_f32(_x: f32) -> f32 {
     unreachable!()
 }
-/// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust,
-/// so this rounds half-way cases to the number with an even least significant digit.
-///
-/// May raise an inexact floating-point exception if the argument is not an integer.
-/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
-/// cannot actually be utilized from Rust code.
-/// In other words, this intrinsic is equivalent in behavior to `nearbyintf64` and `roundevenf64`.
-///
-/// The stabilized version of this intrinsic is
-/// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even)
-#[rustc_intrinsic]
-#[rustc_intrinsic_must_be_overridden]
-#[rustc_nounwind]
-pub unsafe fn rintf64(_x: f64) -> f64 {
-    unreachable!()
+
+/// To be removed on next bootstrap bump.
+#[cfg(bootstrap)]
+pub fn round_ties_even_f32(x: f32) -> f32 {
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    #[rustc_nounwind]
+    unsafe fn rintf32(_x: f32) -> f32 {
+        unreachable!()
+    }
+
+    // SAFETY: this intrinsic isn't actually unsafe
+    unsafe { rintf32(x) }
 }
-/// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust,
-/// so this rounds half-way cases to the number with an even least significant digit.
-///
-/// May raise an inexact floating-point exception if the argument is not an integer.
-/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
-/// cannot actually be utilized from Rust code.
-/// In other words, this intrinsic is equivalent in behavior to `nearbyintf128` and `roundevenf128`.
+
+/// Provided for compatibility with stdarch. DO NOT USE.
+#[inline(always)]
+pub unsafe fn rintf32(x: f32) -> f32 {
+    round_ties_even_f32(x)
+}
+
+/// Returns the nearest integer to an `f64`. Rounds half-way cases to the number with an even
+/// least significant digit.
 ///
 /// The stabilized version of this intrinsic is
-/// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even)
+/// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even)
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 #[rustc_nounwind]
-pub unsafe fn rintf128(_x: f128) -> f128 {
+#[cfg(not(bootstrap))]
+pub fn round_ties_even_f64(_x: f64) -> f64 {
     unreachable!()
 }
 
-/// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust,
-/// so this rounds half-way cases to the number with an even least significant digit.
-///
-/// This intrinsic does not have a stable counterpart.
-#[rustc_intrinsic]
-#[rustc_intrinsic_must_be_overridden]
-#[rustc_nounwind]
-pub unsafe fn nearbyintf16(_x: f16) -> f16 {
-    unreachable!()
+/// To be removed on next bootstrap bump.
+#[cfg(bootstrap)]
+pub fn round_ties_even_f64(x: f64) -> f64 {
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    #[rustc_nounwind]
+    unsafe fn rintf64(_x: f64) -> f64 {
+        unreachable!()
+    }
+
+    // SAFETY: this intrinsic isn't actually unsafe
+    unsafe { rintf64(x) }
 }
-/// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust,
-/// so this rounds half-way cases to the number with an even least significant digit.
-///
-/// This intrinsic does not have a stable counterpart.
-#[rustc_intrinsic]
-#[rustc_intrinsic_must_be_overridden]
-#[rustc_nounwind]
-pub unsafe fn nearbyintf32(_x: f32) -> f32 {
-    unreachable!()
+
+/// Provided for compatibility with stdarch. DO NOT USE.
+#[inline(always)]
+pub unsafe fn rintf64(x: f64) -> f64 {
+    round_ties_even_f64(x)
 }
-/// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust,
-/// so this rounds half-way cases to the number with an even least significant digit.
+
+/// Returns the nearest integer to an `f128`. Rounds half-way cases to the number with an even
+/// least significant digit.
 ///
-/// This intrinsic does not have a stable counterpart.
+/// The stabilized version of this intrinsic is
+/// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even)
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 #[rustc_nounwind]
-pub unsafe fn nearbyintf64(_x: f64) -> f64 {
+#[cfg(not(bootstrap))]
+pub fn round_ties_even_f128(_x: f128) -> f128 {
     unreachable!()
 }
-/// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust,
-/// so this rounds half-way cases to the number with an even least significant digit.
-///
-/// This intrinsic does not have a stable counterpart.
-#[rustc_intrinsic]
-#[rustc_intrinsic_must_be_overridden]
-#[rustc_nounwind]
-pub unsafe fn nearbyintf128(_x: f128) -> f128 {
-    unreachable!()
+
+/// To be removed on next bootstrap bump.
+#[cfg(bootstrap)]
+pub fn round_ties_even_f128(x: f128) -> f128 {
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    #[rustc_nounwind]
+    unsafe fn rintf128(_x: f128) -> f128 {
+        unreachable!()
+    }
+
+    // SAFETY: this intrinsic isn't actually unsafe
+    unsafe { rintf128(x) }
 }
 
 /// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero.
@@ -2878,47 +2892,6 @@ pub unsafe fn roundf128(_x: f128) -> f128 {
     unreachable!()
 }
 
-/// Returns the nearest integer to an `f16`. Rounds half-way cases to the number
-/// with an even least significant digit.
-///
-/// This intrinsic does not have a stable counterpart.
-#[rustc_intrinsic]
-#[rustc_intrinsic_must_be_overridden]
-#[rustc_nounwind]
-pub unsafe fn roundevenf16(_x: f16) -> f16 {
-    unreachable!()
-}
-/// Returns the nearest integer to an `f32`. Rounds half-way cases to the number
-/// with an even least significant digit.
-///
-/// This intrinsic does not have a stable counterpart.
-#[rustc_intrinsic]
-#[rustc_intrinsic_must_be_overridden]
-#[rustc_nounwind]
-pub unsafe fn roundevenf32(_x: f32) -> f32 {
-    unreachable!()
-}
-/// Returns the nearest integer to an `f64`. Rounds half-way cases to the number
-/// with an even least significant digit.
-///
-/// This intrinsic does not have a stable counterpart.
-#[rustc_intrinsic]
-#[rustc_intrinsic_must_be_overridden]
-#[rustc_nounwind]
-pub unsafe fn roundevenf64(_x: f64) -> f64 {
-    unreachable!()
-}
-/// Returns the nearest integer to an `f128`. Rounds half-way cases to the number
-/// with an even least significant digit.
-///
-/// This intrinsic does not have a stable counterpart.
-#[rustc_intrinsic]
-#[rustc_intrinsic_must_be_overridden]
-#[rustc_nounwind]
-pub unsafe fn roundevenf128(_x: f128) -> f128 {
-    unreachable!()
-}
-
 /// Float addition that allows optimizations based on algebraic rules.
 /// May assume inputs are finite.
 ///