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
This commit is contained in:
commit
a2bb4d748d
@ -340,14 +340,10 @@ fn codegen_float_intrinsic_call<'tcx>(
|
||||
sym::ceilf64 => ("ceil", 1, fx.tcx.types.f64, types::F64),
|
||||
sym::truncf32 => ("truncf", 1, fx.tcx.types.f32, types::F32),
|
||||
sym::truncf64 => ("trunc", 1, fx.tcx.types.f64, types::F64),
|
||||
sym::rintf32 => ("rintf", 1, fx.tcx.types.f32, types::F32),
|
||||
sym::rintf64 => ("rint", 1, fx.tcx.types.f64, types::F64),
|
||||
sym::round_ties_even_f32 => ("rintf", 1, fx.tcx.types.f32, types::F32),
|
||||
sym::round_ties_even_f64 => ("rint", 1, fx.tcx.types.f64, types::F64),
|
||||
sym::roundf32 => ("roundf", 1, fx.tcx.types.f32, types::F32),
|
||||
sym::roundf64 => ("round", 1, fx.tcx.types.f64, types::F64),
|
||||
sym::roundevenf32 => ("roundevenf", 1, fx.tcx.types.f32, types::F32),
|
||||
sym::roundevenf64 => ("roundeven", 1, fx.tcx.types.f64, types::F64),
|
||||
sym::nearbyintf32 => ("nearbyintf", 1, fx.tcx.types.f32, types::F32),
|
||||
sym::nearbyintf64 => ("nearbyint", 1, fx.tcx.types.f64, types::F64),
|
||||
sym::sinf32 => ("sinf", 1, fx.tcx.types.f32, types::F32),
|
||||
sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64),
|
||||
sym::cosf32 => ("cosf", 1, fx.tcx.types.f32, types::F32),
|
||||
@ -399,8 +395,8 @@ fn codegen_float_intrinsic_call<'tcx>(
|
||||
| sym::ceilf64
|
||||
| sym::truncf32
|
||||
| sym::truncf64
|
||||
| sym::nearbyintf32
|
||||
| sym::nearbyintf64
|
||||
| sym::round_ties_even_f32
|
||||
| sym::round_ties_even_f64
|
||||
| sym::sqrtf32
|
||||
| sym::sqrtf64 => {
|
||||
let val = match intrinsic {
|
||||
@ -408,7 +404,9 @@ fn codegen_float_intrinsic_call<'tcx>(
|
||||
sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]),
|
||||
sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]),
|
||||
sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(args[0]),
|
||||
sym::nearbyintf32 | sym::nearbyintf64 => fx.bcx.ins().nearest(args[0]),
|
||||
sym::round_ties_even_f32 | sym::round_ties_even_f64 => {
|
||||
fx.bcx.ins().nearest(args[0])
|
||||
}
|
||||
sym::sqrtf32 | sym::sqrtf64 => fx.bcx.ins().sqrt(args[0]),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
@ -84,14 +84,11 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
|
||||
sym::ceilf64 => "ceil",
|
||||
sym::truncf32 => "truncf",
|
||||
sym::truncf64 => "trunc",
|
||||
sym::rintf32 => "rintf",
|
||||
sym::rintf64 => "rint",
|
||||
sym::nearbyintf32 => "nearbyintf",
|
||||
sym::nearbyintf64 => "nearbyint",
|
||||
// We match the LLVM backend and lower this to `rint`.
|
||||
sym::round_ties_even_f32 => "rintf",
|
||||
sym::round_ties_even_f64 => "rint",
|
||||
sym::roundf32 => "roundf",
|
||||
sym::roundf64 => "round",
|
||||
sym::roundevenf32 => "roundevenf",
|
||||
sym::roundevenf64 => "roundeven",
|
||||
sym::abort => "abort",
|
||||
_ => return None,
|
||||
};
|
||||
|
@ -127,15 +127,14 @@ fn get_simple_intrinsic<'ll>(
|
||||
sym::truncf64 => "llvm.trunc.f64",
|
||||
sym::truncf128 => "llvm.trunc.f128",
|
||||
|
||||
sym::rintf16 => "llvm.rint.f16",
|
||||
sym::rintf32 => "llvm.rint.f32",
|
||||
sym::rintf64 => "llvm.rint.f64",
|
||||
sym::rintf128 => "llvm.rint.f128",
|
||||
|
||||
sym::nearbyintf16 => "llvm.nearbyint.f16",
|
||||
sym::nearbyintf32 => "llvm.nearbyint.f32",
|
||||
sym::nearbyintf64 => "llvm.nearbyint.f64",
|
||||
sym::nearbyintf128 => "llvm.nearbyint.f128",
|
||||
// We could use any of `rint`, `nearbyint`, or `roundeven`
|
||||
// for this -- they are all identical in semantics when
|
||||
// assuming the default FP environment.
|
||||
// `rint` is what we used for $forever.
|
||||
sym::round_ties_even_f16 => "llvm.rint.f16",
|
||||
sym::round_ties_even_f32 => "llvm.rint.f32",
|
||||
sym::round_ties_even_f64 => "llvm.rint.f64",
|
||||
sym::round_ties_even_f128 => "llvm.rint.f128",
|
||||
|
||||
sym::roundf16 => "llvm.round.f16",
|
||||
sym::roundf32 => "llvm.round.f32",
|
||||
@ -144,11 +143,6 @@ fn get_simple_intrinsic<'ll>(
|
||||
|
||||
sym::ptr_mask => "llvm.ptrmask",
|
||||
|
||||
sym::roundevenf16 => "llvm.roundeven.f16",
|
||||
sym::roundevenf32 => "llvm.roundeven.f32",
|
||||
sym::roundevenf64 => "llvm.roundeven.f64",
|
||||
sym::roundevenf128 => "llvm.roundeven.f128",
|
||||
|
||||
_ => return None,
|
||||
};
|
||||
Some(cx.get_intrinsic(llvm_name))
|
||||
|
@ -140,6 +140,10 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
|
||||
| sym::fmul_algebraic
|
||||
| sym::fdiv_algebraic
|
||||
| sym::frem_algebraic
|
||||
| sym::round_ties_even_f16
|
||||
| sym::round_ties_even_f32
|
||||
| sym::round_ties_even_f64
|
||||
| sym::round_ties_even_f128
|
||||
| sym::const_eval_select => hir::Safety::Safe,
|
||||
_ => hir::Safety::Unsafe,
|
||||
};
|
||||
@ -416,26 +420,16 @@ pub fn check_intrinsic_type(
|
||||
sym::truncf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
|
||||
sym::truncf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
|
||||
|
||||
sym::rintf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
|
||||
sym::rintf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
|
||||
sym::rintf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
|
||||
sym::rintf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
|
||||
|
||||
sym::nearbyintf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
|
||||
sym::nearbyintf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
|
||||
sym::nearbyintf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
|
||||
sym::nearbyintf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
|
||||
sym::round_ties_even_f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
|
||||
sym::round_ties_even_f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
|
||||
sym::round_ties_even_f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
|
||||
sym::round_ties_even_f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
|
||||
|
||||
sym::roundf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
|
||||
sym::roundf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
|
||||
sym::roundf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
|
||||
sym::roundf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
|
||||
|
||||
sym::roundevenf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
|
||||
sym::roundevenf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
|
||||
sym::roundevenf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
|
||||
sym::roundevenf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
|
||||
|
||||
sym::volatile_load | sym::unaligned_volatile_load => {
|
||||
(1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0))
|
||||
}
|
||||
|
@ -1367,10 +1367,6 @@ symbols! {
|
||||
native_link_modifiers_whole_archive,
|
||||
natvis_file,
|
||||
ne,
|
||||
nearbyintf128,
|
||||
nearbyintf16,
|
||||
nearbyintf32,
|
||||
nearbyintf64,
|
||||
needs_allocator,
|
||||
needs_drop,
|
||||
needs_panic_runtime,
|
||||
@ -1688,20 +1684,16 @@ symbols! {
|
||||
return_position_impl_trait_in_trait,
|
||||
return_type_notation,
|
||||
rhs,
|
||||
rintf128,
|
||||
rintf16,
|
||||
rintf32,
|
||||
rintf64,
|
||||
riscv_target_feature,
|
||||
rlib,
|
||||
ropi,
|
||||
ropi_rwpi: "ropi-rwpi",
|
||||
rotate_left,
|
||||
rotate_right,
|
||||
roundevenf128,
|
||||
roundevenf16,
|
||||
roundevenf32,
|
||||
roundevenf64,
|
||||
round_ties_even_f128,
|
||||
round_ties_even_f16,
|
||||
round_ties_even_f32,
|
||||
round_ties_even_f64,
|
||||
roundf128,
|
||||
roundf16,
|
||||
roundf32,
|
||||
|
@ -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`.
|
||||
|
||||
/// 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) }
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// [`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 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 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) }
|
||||
}
|
||||
|
||||
/// 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 `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 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 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.
|
||||
///
|
||||
|
@ -126,7 +126,7 @@ impl f128 {
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub fn round_ties_even(self) -> f128 {
|
||||
unsafe { intrinsics::rintf128(self) }
|
||||
intrinsics::round_ties_even_f128(self)
|
||||
}
|
||||
|
||||
/// Returns the integer part of `self`.
|
||||
|
@ -126,7 +126,7 @@ impl f16 {
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub fn round_ties_even(self) -> f16 {
|
||||
unsafe { intrinsics::rintf16(self) }
|
||||
intrinsics::round_ties_even_f16(self)
|
||||
}
|
||||
|
||||
/// Returns the integer part of `self`.
|
||||
|
@ -122,7 +122,7 @@ impl f32 {
|
||||
#[stable(feature = "round_ties_even", since = "1.77.0")]
|
||||
#[inline]
|
||||
pub fn round_ties_even(self) -> f32 {
|
||||
unsafe { intrinsics::rintf32(self) }
|
||||
intrinsics::round_ties_even_f32(self)
|
||||
}
|
||||
|
||||
/// Returns the integer part of `self`.
|
||||
|
@ -122,7 +122,7 @@ impl f64 {
|
||||
#[stable(feature = "round_ties_even", since = "1.77.0")]
|
||||
#[inline]
|
||||
pub fn round_ties_even(self) -> f64 {
|
||||
unsafe { intrinsics::rintf64(self) }
|
||||
intrinsics::round_ties_even_f64(self)
|
||||
}
|
||||
|
||||
/// Returns the integer part of `self`.
|
||||
|
@ -145,7 +145,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
this.write_scalar(Scalar::from_bool(branch), dest)?;
|
||||
}
|
||||
|
||||
"floorf16" | "ceilf16" | "truncf16" | "roundf16" | "rintf16" => {
|
||||
"floorf16" | "ceilf16" | "truncf16" | "roundf16" | "round_ties_even_f16" => {
|
||||
let [f] = check_arg_count(args)?;
|
||||
let f = this.read_scalar(f)?.to_f16()?;
|
||||
let mode = match intrinsic_name {
|
||||
@ -153,14 +153,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
"ceilf16" => Round::TowardPositive,
|
||||
"truncf16" => Round::TowardZero,
|
||||
"roundf16" => Round::NearestTiesToAway,
|
||||
"rintf16" => Round::NearestTiesToEven,
|
||||
"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" | "rintf32" => {
|
||||
"floorf32" | "ceilf32" | "truncf32" | "roundf32" | "round_ties_even_f32" => {
|
||||
let [f] = check_arg_count(args)?;
|
||||
let f = this.read_scalar(f)?.to_f32()?;
|
||||
let mode = match intrinsic_name {
|
||||
@ -168,14 +168,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
"ceilf32" => Round::TowardPositive,
|
||||
"truncf32" => Round::TowardZero,
|
||||
"roundf32" => Round::NearestTiesToAway,
|
||||
"rintf32" => Round::NearestTiesToEven,
|
||||
"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" | "rintf64" => {
|
||||
"floorf64" | "ceilf64" | "truncf64" | "roundf64" | "round_ties_even_f64" => {
|
||||
let [f] = check_arg_count(args)?;
|
||||
let f = this.read_scalar(f)?.to_f64()?;
|
||||
let mode = match intrinsic_name {
|
||||
@ -183,14 +183,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
"ceilf64" => Round::TowardPositive,
|
||||
"truncf64" => Round::TowardZero,
|
||||
"roundf64" => Round::NearestTiesToAway,
|
||||
"rintf64" => Round::NearestTiesToEven,
|
||||
"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" | "rintf128" => {
|
||||
"floorf128" | "ceilf128" | "truncf128" | "roundf128" | "round_ties_even_f128" => {
|
||||
let [f] = check_arg_count(args)?;
|
||||
let f = this.read_scalar(f)?.to_f128()?;
|
||||
let mode = match intrinsic_name {
|
||||
@ -198,7 +198,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
"ceilf128" => Round::TowardPositive,
|
||||
"truncf128" => Round::TowardZero,
|
||||
"roundf128" => Round::NearestTiesToAway,
|
||||
"rintf128" => Round::NearestTiesToEven,
|
||||
"round_ties_even_f128" => Round::NearestTiesToEven,
|
||||
_ => bug!(),
|
||||
};
|
||||
let res = f.round_to_integral(mode).value;
|
||||
|
@ -1,18 +0,0 @@
|
||||
#![crate_type = "lib"]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::intrinsics;
|
||||
|
||||
// CHECK-LABEL: @nearbyintf32
|
||||
#[no_mangle]
|
||||
pub unsafe fn nearbyintf32(a: f32) -> f32 {
|
||||
// CHECK: llvm.nearbyint.f32
|
||||
intrinsics::nearbyintf32(a)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @nearbyintf64
|
||||
#[no_mangle]
|
||||
pub unsafe fn nearbyintf64(a: f64) -> f64 {
|
||||
// CHECK: llvm.nearbyint.f64
|
||||
intrinsics::nearbyintf64(a)
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
//@ run-pass
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::intrinsics::*;
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
assert_eq!(nearbyintf32(5.234f32), 5f32);
|
||||
assert_eq!(nearbyintf64(6.777f64), 7f64);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user