intrinsics: unify rint, roundeven, nearbyint in a single round_ties_even intrinsic
This commit is contained in:
parent
019fc4de2f
commit
04e7a10af6
13 changed files with 111 additions and 208 deletions
|
@ -340,14 +340,10 @@ fn codegen_float_intrinsic_call<'tcx>(
|
||||||
sym::ceilf64 => ("ceil", 1, fx.tcx.types.f64, types::F64),
|
sym::ceilf64 => ("ceil", 1, fx.tcx.types.f64, types::F64),
|
||||||
sym::truncf32 => ("truncf", 1, fx.tcx.types.f32, types::F32),
|
sym::truncf32 => ("truncf", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::truncf64 => ("trunc", 1, fx.tcx.types.f64, types::F64),
|
sym::truncf64 => ("trunc", 1, fx.tcx.types.f64, types::F64),
|
||||||
sym::rintf32 => ("rintf", 1, fx.tcx.types.f32, types::F32),
|
sym::round_ties_even_f32 => ("rintf", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::rintf64 => ("rint", 1, fx.tcx.types.f64, types::F64),
|
sym::round_ties_even_f64 => ("rint", 1, fx.tcx.types.f64, types::F64),
|
||||||
sym::roundf32 => ("roundf", 1, fx.tcx.types.f32, types::F32),
|
sym::roundf32 => ("roundf", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::roundf64 => ("round", 1, fx.tcx.types.f64, types::F64),
|
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::sinf32 => ("sinf", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64),
|
sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64),
|
||||||
sym::cosf32 => ("cosf", 1, fx.tcx.types.f32, types::F32),
|
sym::cosf32 => ("cosf", 1, fx.tcx.types.f32, types::F32),
|
||||||
|
@ -399,8 +395,8 @@ fn codegen_float_intrinsic_call<'tcx>(
|
||||||
| sym::ceilf64
|
| sym::ceilf64
|
||||||
| sym::truncf32
|
| sym::truncf32
|
||||||
| sym::truncf64
|
| sym::truncf64
|
||||||
| sym::nearbyintf32
|
| sym::round_ties_even_f32
|
||||||
| sym::nearbyintf64
|
| sym::round_ties_even_f64
|
||||||
| sym::sqrtf32
|
| sym::sqrtf32
|
||||||
| sym::sqrtf64 => {
|
| sym::sqrtf64 => {
|
||||||
let val = match intrinsic {
|
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::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]),
|
||||||
sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]),
|
sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]),
|
||||||
sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(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]),
|
sym::sqrtf32 | sym::sqrtf64 => fx.bcx.ins().sqrt(args[0]),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -84,14 +84,11 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
|
||||||
sym::ceilf64 => "ceil",
|
sym::ceilf64 => "ceil",
|
||||||
sym::truncf32 => "truncf",
|
sym::truncf32 => "truncf",
|
||||||
sym::truncf64 => "trunc",
|
sym::truncf64 => "trunc",
|
||||||
sym::rintf32 => "rintf",
|
// We match the LLVM backend and lower this to `rint`.
|
||||||
sym::rintf64 => "rint",
|
sym::round_ties_even_f32 => "rintf",
|
||||||
sym::nearbyintf32 => "nearbyintf",
|
sym::round_ties_even_f64 => "rint",
|
||||||
sym::nearbyintf64 => "nearbyint",
|
|
||||||
sym::roundf32 => "roundf",
|
sym::roundf32 => "roundf",
|
||||||
sym::roundf64 => "round",
|
sym::roundf64 => "round",
|
||||||
sym::roundevenf32 => "roundevenf",
|
|
||||||
sym::roundevenf64 => "roundeven",
|
|
||||||
sym::abort => "abort",
|
sym::abort => "abort",
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
|
@ -126,15 +126,14 @@ fn get_simple_intrinsic<'ll>(
|
||||||
sym::truncf64 => "llvm.trunc.f64",
|
sym::truncf64 => "llvm.trunc.f64",
|
||||||
sym::truncf128 => "llvm.trunc.f128",
|
sym::truncf128 => "llvm.trunc.f128",
|
||||||
|
|
||||||
sym::rintf16 => "llvm.rint.f16",
|
// We could use any of `rint`, `nearbyint`, or `roundeven`
|
||||||
sym::rintf32 => "llvm.rint.f32",
|
// for this -- they are all identical in semantics when
|
||||||
sym::rintf64 => "llvm.rint.f64",
|
// assuming the default FP environment.
|
||||||
sym::rintf128 => "llvm.rint.f128",
|
// `rint` is what we used for $forever.
|
||||||
|
sym::round_ties_even_f16 => "llvm.rint.f16",
|
||||||
sym::nearbyintf16 => "llvm.nearbyint.f16",
|
sym::round_ties_even_f32 => "llvm.rint.f32",
|
||||||
sym::nearbyintf32 => "llvm.nearbyint.f32",
|
sym::round_ties_even_f64 => "llvm.rint.f64",
|
||||||
sym::nearbyintf64 => "llvm.nearbyint.f64",
|
sym::round_ties_even_f128 => "llvm.rint.f128",
|
||||||
sym::nearbyintf128 => "llvm.nearbyint.f128",
|
|
||||||
|
|
||||||
sym::roundf16 => "llvm.round.f16",
|
sym::roundf16 => "llvm.round.f16",
|
||||||
sym::roundf32 => "llvm.round.f32",
|
sym::roundf32 => "llvm.round.f32",
|
||||||
|
@ -143,11 +142,6 @@ fn get_simple_intrinsic<'ll>(
|
||||||
|
|
||||||
sym::ptr_mask => "llvm.ptrmask",
|
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,
|
_ => return None,
|
||||||
};
|
};
|
||||||
Some(cx.get_intrinsic(llvm_name))
|
Some(cx.get_intrinsic(llvm_name))
|
||||||
|
|
|
@ -398,26 +398,16 @@ pub fn check_intrinsic_type(
|
||||||
sym::truncf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
|
sym::truncf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
|
||||||
sym::truncf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
|
sym::truncf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
|
||||||
|
|
||||||
sym::rintf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
|
sym::round_ties_even_f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
|
||||||
sym::rintf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
|
sym::round_ties_even_f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
|
||||||
sym::rintf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
|
sym::round_ties_even_f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
|
||||||
sym::rintf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
|
sym::round_ties_even_f128 => (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::roundf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
|
sym::roundf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
|
||||||
sym::roundf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
|
sym::roundf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
|
||||||
sym::roundf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
|
sym::roundf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
|
||||||
sym::roundf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
|
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 => {
|
sym::volatile_load | sym::unaligned_volatile_load => {
|
||||||
(1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0))
|
(1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1337,10 +1337,6 @@ symbols! {
|
||||||
native_link_modifiers_whole_archive,
|
native_link_modifiers_whole_archive,
|
||||||
natvis_file,
|
natvis_file,
|
||||||
ne,
|
ne,
|
||||||
nearbyintf128,
|
|
||||||
nearbyintf16,
|
|
||||||
nearbyintf32,
|
|
||||||
nearbyintf64,
|
|
||||||
needs_allocator,
|
needs_allocator,
|
||||||
needs_drop,
|
needs_drop,
|
||||||
needs_panic_runtime,
|
needs_panic_runtime,
|
||||||
|
@ -1655,20 +1651,16 @@ symbols! {
|
||||||
return_position_impl_trait_in_trait,
|
return_position_impl_trait_in_trait,
|
||||||
return_type_notation,
|
return_type_notation,
|
||||||
rhs,
|
rhs,
|
||||||
rintf128,
|
|
||||||
rintf16,
|
|
||||||
rintf32,
|
|
||||||
rintf64,
|
|
||||||
riscv_target_feature,
|
riscv_target_feature,
|
||||||
rlib,
|
rlib,
|
||||||
ropi,
|
ropi,
|
||||||
ropi_rwpi: "ropi-rwpi",
|
ropi_rwpi: "ropi-rwpi",
|
||||||
rotate_left,
|
rotate_left,
|
||||||
rotate_right,
|
rotate_right,
|
||||||
roundevenf128,
|
round_ties_even_f128,
|
||||||
roundevenf16,
|
round_ties_even_f16,
|
||||||
roundevenf32,
|
round_ties_even_f32,
|
||||||
roundevenf64,
|
round_ties_even_f64,
|
||||||
roundf128,
|
roundf128,
|
||||||
roundf16,
|
roundf16,
|
||||||
roundf32,
|
roundf32,
|
||||||
|
|
|
@ -2739,110 +2739,112 @@ pub unsafe fn truncf128(_x: f128) -> f128 {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust,
|
/// Returns the nearest integer to an `f16`. Rounds half-way cases to the number with an even
|
||||||
/// so this rounds half-way cases to the number with an even least significant digit.
|
/// 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`.
|
|
||||||
///
|
///
|
||||||
/// The stabilized version of this intrinsic is
|
/// The stabilized version of this intrinsic is
|
||||||
/// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even)
|
/// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even)
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
#[rustc_intrinsic_must_be_overridden]
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
#[rustc_nounwind]
|
#[rustc_nounwind]
|
||||||
pub unsafe fn rintf16(_x: f16) -> f16 {
|
#[cfg(not(bootstrap))]
|
||||||
|
pub unsafe fn round_ties_even_f16(_x: f16) -> f16 {
|
||||||
unreachable!()
|
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.
|
/// To be removed on next bootstrap bump.
|
||||||
///
|
#[cfg(bootstrap)]
|
||||||
/// May raise an inexact floating-point exception if the argument is not an integer.
|
pub unsafe fn round_ties_even_f16(x: f16) -> f16 {
|
||||||
/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
|
#[rustc_intrinsic]
|
||||||
/// cannot actually be utilized from Rust code.
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
/// In other words, this intrinsic is equivalent in behavior to `nearbyintf32` and `roundevenf32`.
|
#[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
|
/// The stabilized version of this intrinsic is
|
||||||
/// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even)
|
/// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even)
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
#[rustc_intrinsic_must_be_overridden]
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
#[rustc_nounwind]
|
#[rustc_nounwind]
|
||||||
pub unsafe fn rintf32(_x: f32) -> f32 {
|
#[cfg(not(bootstrap))]
|
||||||
|
pub unsafe fn round_ties_even_f32(_x: f32) -> f32 {
|
||||||
unreachable!()
|
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.
|
/// To be removed on next bootstrap bump.
|
||||||
///
|
#[cfg(bootstrap)]
|
||||||
/// May raise an inexact floating-point exception if the argument is not an integer.
|
pub unsafe fn round_ties_even_f32(x: f32) -> f32 {
|
||||||
/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
|
#[rustc_intrinsic]
|
||||||
/// cannot actually be utilized from Rust code.
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
/// In other words, this intrinsic is equivalent in behavior to `nearbyintf64` and `roundevenf64`.
|
#[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
|
/// The stabilized version of this intrinsic is
|
||||||
/// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even)
|
/// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even)
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
#[rustc_intrinsic_must_be_overridden]
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
#[rustc_nounwind]
|
#[rustc_nounwind]
|
||||||
pub unsafe fn rintf64(_x: f64) -> f64 {
|
#[cfg(not(bootstrap))]
|
||||||
|
pub unsafe fn round_ties_even_f64(_x: f64) -> f64 {
|
||||||
unreachable!()
|
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.
|
/// To be removed on next bootstrap bump.
|
||||||
///
|
#[cfg(bootstrap)]
|
||||||
/// May raise an inexact floating-point exception if the argument is not an integer.
|
pub unsafe fn round_ties_even_f64(x: f64) -> f64 {
|
||||||
/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
|
#[rustc_intrinsic]
|
||||||
/// cannot actually be utilized from Rust code.
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
/// In other words, this intrinsic is equivalent in behavior to `nearbyintf128` and `roundevenf128`.
|
#[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
|
/// The stabilized version of this intrinsic is
|
||||||
/// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even)
|
/// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even)
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
#[rustc_intrinsic_must_be_overridden]
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
#[rustc_nounwind]
|
#[rustc_nounwind]
|
||||||
pub unsafe fn rintf128(_x: f128) -> f128 {
|
#[cfg(not(bootstrap))]
|
||||||
|
pub unsafe fn round_ties_even_f128(_x: f128) -> f128 {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust,
|
/// To be removed on next bootstrap bump.
|
||||||
/// so this rounds half-way cases to the number with an even least significant digit.
|
#[cfg(bootstrap)]
|
||||||
///
|
pub unsafe fn round_ties_even_f128(x: f128) -> f128 {
|
||||||
/// This intrinsic does not have a stable counterpart.
|
#[rustc_intrinsic]
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
#[rustc_intrinsic_must_be_overridden]
|
#[rustc_nounwind]
|
||||||
#[rustc_nounwind]
|
unsafe fn rintf128(_x: f128) -> f128 {
|
||||||
pub unsafe fn nearbyintf16(_x: f16) -> f16 {
|
unreachable!()
|
||||||
unreachable!()
|
}
|
||||||
}
|
|
||||||
/// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust,
|
// SAFETY: this intrinsic isn't actually unsafe
|
||||||
/// so this rounds half-way cases to the number with an even least significant digit.
|
unsafe { rintf128(x) }
|
||||||
///
|
|
||||||
/// 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!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero.
|
/// 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!()
|
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.
|
/// Float addition that allows optimizations based on algebraic rules.
|
||||||
/// May assume inputs are finite.
|
/// May assume inputs are finite.
|
||||||
///
|
///
|
||||||
|
|
|
@ -129,7 +129,7 @@ impl f128 {
|
||||||
#[unstable(feature = "f128", issue = "116909")]
|
#[unstable(feature = "f128", issue = "116909")]
|
||||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||||
pub fn round_ties_even(self) -> f128 {
|
pub fn round_ties_even(self) -> f128 {
|
||||||
unsafe { intrinsics::rintf128(self) }
|
unsafe { intrinsics::round_ties_even_f128(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the integer part of `self`.
|
/// Returns the integer part of `self`.
|
||||||
|
|
|
@ -129,7 +129,7 @@ impl f16 {
|
||||||
#[unstable(feature = "f16", issue = "116909")]
|
#[unstable(feature = "f16", issue = "116909")]
|
||||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||||
pub fn round_ties_even(self) -> f16 {
|
pub fn round_ties_even(self) -> f16 {
|
||||||
unsafe { intrinsics::rintf16(self) }
|
unsafe { intrinsics::round_ties_even_f16(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the integer part of `self`.
|
/// Returns the integer part of `self`.
|
||||||
|
|
|
@ -125,7 +125,7 @@ impl f32 {
|
||||||
#[stable(feature = "round_ties_even", since = "1.77.0")]
|
#[stable(feature = "round_ties_even", since = "1.77.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn round_ties_even(self) -> f32 {
|
pub fn round_ties_even(self) -> f32 {
|
||||||
unsafe { intrinsics::rintf32(self) }
|
unsafe { intrinsics::round_ties_even_f32(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the integer part of `self`.
|
/// Returns the integer part of `self`.
|
||||||
|
|
|
@ -125,7 +125,7 @@ impl f64 {
|
||||||
#[stable(feature = "round_ties_even", since = "1.77.0")]
|
#[stable(feature = "round_ties_even", since = "1.77.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn round_ties_even(self) -> f64 {
|
pub fn round_ties_even(self) -> f64 {
|
||||||
unsafe { intrinsics::rintf64(self) }
|
unsafe { intrinsics::round_ties_even_f64(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the integer part of `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)?;
|
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] = check_arg_count(args)?;
|
||||||
let f = this.read_scalar(f)?.to_f16()?;
|
let f = this.read_scalar(f)?.to_f16()?;
|
||||||
let mode = match intrinsic_name {
|
let mode = match intrinsic_name {
|
||||||
|
@ -153,14 +153,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||||
"ceilf16" => Round::TowardPositive,
|
"ceilf16" => Round::TowardPositive,
|
||||||
"truncf16" => Round::TowardZero,
|
"truncf16" => Round::TowardZero,
|
||||||
"roundf16" => Round::NearestTiesToAway,
|
"roundf16" => Round::NearestTiesToAway,
|
||||||
"rintf16" => Round::NearestTiesToEven,
|
"round_ties_even_f16" => Round::NearestTiesToEven,
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
let res = f.round_to_integral(mode).value;
|
let res = f.round_to_integral(mode).value;
|
||||||
let res = this.adjust_nan(res, &[f]);
|
let res = this.adjust_nan(res, &[f]);
|
||||||
this.write_scalar(res, dest)?;
|
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] = check_arg_count(args)?;
|
||||||
let f = this.read_scalar(f)?.to_f32()?;
|
let f = this.read_scalar(f)?.to_f32()?;
|
||||||
let mode = match intrinsic_name {
|
let mode = match intrinsic_name {
|
||||||
|
@ -168,14 +168,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||||
"ceilf32" => Round::TowardPositive,
|
"ceilf32" => Round::TowardPositive,
|
||||||
"truncf32" => Round::TowardZero,
|
"truncf32" => Round::TowardZero,
|
||||||
"roundf32" => Round::NearestTiesToAway,
|
"roundf32" => Round::NearestTiesToAway,
|
||||||
"rintf32" => Round::NearestTiesToEven,
|
"round_ties_even_f32" => Round::NearestTiesToEven,
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
let res = f.round_to_integral(mode).value;
|
let res = f.round_to_integral(mode).value;
|
||||||
let res = this.adjust_nan(res, &[f]);
|
let res = this.adjust_nan(res, &[f]);
|
||||||
this.write_scalar(res, dest)?;
|
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] = check_arg_count(args)?;
|
||||||
let f = this.read_scalar(f)?.to_f64()?;
|
let f = this.read_scalar(f)?.to_f64()?;
|
||||||
let mode = match intrinsic_name {
|
let mode = match intrinsic_name {
|
||||||
|
@ -183,14 +183,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||||
"ceilf64" => Round::TowardPositive,
|
"ceilf64" => Round::TowardPositive,
|
||||||
"truncf64" => Round::TowardZero,
|
"truncf64" => Round::TowardZero,
|
||||||
"roundf64" => Round::NearestTiesToAway,
|
"roundf64" => Round::NearestTiesToAway,
|
||||||
"rintf64" => Round::NearestTiesToEven,
|
"round_ties_even_f64" => Round::NearestTiesToEven,
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
let res = f.round_to_integral(mode).value;
|
let res = f.round_to_integral(mode).value;
|
||||||
let res = this.adjust_nan(res, &[f]);
|
let res = this.adjust_nan(res, &[f]);
|
||||||
this.write_scalar(res, dest)?;
|
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] = check_arg_count(args)?;
|
||||||
let f = this.read_scalar(f)?.to_f128()?;
|
let f = this.read_scalar(f)?.to_f128()?;
|
||||||
let mode = match intrinsic_name {
|
let mode = match intrinsic_name {
|
||||||
|
@ -198,7 +198,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||||
"ceilf128" => Round::TowardPositive,
|
"ceilf128" => Round::TowardPositive,
|
||||||
"truncf128" => Round::TowardZero,
|
"truncf128" => Round::TowardZero,
|
||||||
"roundf128" => Round::NearestTiesToAway,
|
"roundf128" => Round::NearestTiesToAway,
|
||||||
"rintf128" => Round::NearestTiesToEven,
|
"round_ties_even_f128" => Round::NearestTiesToEven,
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
let res = f.round_to_integral(mode).value;
|
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…
Add table
Add a link
Reference in a new issue