-
Notifications
You must be signed in to change notification settings - Fork 13.3k
intrinsics: unify rint, roundeven, nearbyint in a single round_ties_even intrinsic #136543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2739,110 +2739,112 @@ 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 unsafe fn round_ties_even_f16(_x: f16) -> f16 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the latest on safe vs. unsafe intrinsics? There shouldn't be any preconditions here so it could probably be updated while you're at it (not necessary ofc). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure I guess I can mark this safe while I am at it, though it is strangely inconsistent with the other rounding intrinsics. |
||
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 unsafe 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 unsafe 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`. | ||
|
||
/// To be removed on next bootstrap bump. | ||
#[cfg(bootstrap)] | ||
pub unsafe 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 `f64`. Rounds half-way cases to the number with an even | ||
/// least significant digit. | ||
/// | ||
/// 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 { | ||
#[cfg(not(bootstrap))] | ||
pub unsafe fn round_ties_even_f64(_x: f64) -> f64 { | ||
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. | ||
/// | ||
/// 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`. | ||
|
||
/// To be removed on next bootstrap bump. | ||
#[cfg(bootstrap)] | ||
pub unsafe 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 `f128`. 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) | ||
#[rustc_intrinsic] | ||
#[rustc_intrinsic_must_be_overridden] | ||
#[rustc_nounwind] | ||
pub unsafe fn rintf128(_x: f128) -> f128 { | ||
#[cfg(not(bootstrap))] | ||
pub unsafe fn round_ties_even_f128(_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. | ||
/// | ||
/// 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!() | ||
} | ||
/// 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!() | ||
} | ||
/// 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. | ||
/// | ||
/// This intrinsic does not have a stable counterpart. | ||
#[rustc_intrinsic] | ||
#[rustc_intrinsic_must_be_overridden] | ||
#[rustc_nounwind] | ||
pub unsafe fn nearbyintf64(_x: f64) -> f64 { | ||
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 unsafe 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. | ||
|
@@ -2886,47 +2888,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. | ||
/// | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means the cranelift backend will actually change behavior with this PR -- the
round_ties_even
functions will lower to the "nearest" instruction rather than torint
libcalls. @bjorn3 is that okay?I am also surprised to not see a case for
round
here (rounding half-way cases away from zero); is that the one rounding mode cranelit does not support natively?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this ever lowers to
nearbyint
then we do not currently provide that in libm so there may be linking problems on targets without a systemlibm
. I don't expect this to be a problem for cranelift though.