Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6f39172

Browse files
committedFeb 4, 2025·
intrinsics: unify rint, roundeven, nearbyint in a single round_ties_even intrinsic
1 parent 019fc4d commit 6f39172

File tree

11 files changed

+111
-179
lines changed

11 files changed

+111
-179
lines changed
 

‎compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -340,14 +340,10 @@ fn codegen_float_intrinsic_call<'tcx>(
340340
sym::ceilf64 => ("ceil", 1, fx.tcx.types.f64, types::F64),
341341
sym::truncf32 => ("truncf", 1, fx.tcx.types.f32, types::F32),
342342
sym::truncf64 => ("trunc", 1, fx.tcx.types.f64, types::F64),
343-
sym::rintf32 => ("rintf", 1, fx.tcx.types.f32, types::F32),
344-
sym::rintf64 => ("rint", 1, fx.tcx.types.f64, types::F64),
343+
sym::round_ties_even_f32 => ("rintf", 1, fx.tcx.types.f32, types::F32),
344+
sym::round_ties_even_f64 => ("rint", 1, fx.tcx.types.f64, types::F64),
345345
sym::roundf32 => ("roundf", 1, fx.tcx.types.f32, types::F32),
346346
sym::roundf64 => ("round", 1, fx.tcx.types.f64, types::F64),
347-
sym::roundevenf32 => ("roundevenf", 1, fx.tcx.types.f32, types::F32),
348-
sym::roundevenf64 => ("roundeven", 1, fx.tcx.types.f64, types::F64),
349-
sym::nearbyintf32 => ("nearbyintf", 1, fx.tcx.types.f32, types::F32),
350-
sym::nearbyintf64 => ("nearbyint", 1, fx.tcx.types.f64, types::F64),
351347
sym::sinf32 => ("sinf", 1, fx.tcx.types.f32, types::F32),
352348
sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64),
353349
sym::cosf32 => ("cosf", 1, fx.tcx.types.f32, types::F32),
@@ -399,16 +395,18 @@ fn codegen_float_intrinsic_call<'tcx>(
399395
| sym::ceilf64
400396
| sym::truncf32
401397
| sym::truncf64
402-
| sym::nearbyintf32
403-
| sym::nearbyintf64
398+
| sym::round_ties_even_f32
399+
| sym::round_ties_even_f64
404400
| sym::sqrtf32
405401
| sym::sqrtf64 => {
406402
let val = match intrinsic {
407403
sym::fabsf32 | sym::fabsf64 => fx.bcx.ins().fabs(args[0]),
408404
sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]),
409405
sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]),
410406
sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(args[0]),
411-
sym::nearbyintf32 | sym::nearbyintf64 => fx.bcx.ins().nearest(args[0]),
407+
sym::round_ties_even_f32 | sym::round_ties_even_f64 => {
408+
fx.bcx.ins().nearest(args[0])
409+
}
412410
sym::sqrtf32 | sym::sqrtf64 => fx.bcx.ins().sqrt(args[0]),
413411
_ => unreachable!(),
414412
};

‎compiler/rustc_codegen_gcc/src/intrinsic/mod.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,11 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
8484
sym::ceilf64 => "ceil",
8585
sym::truncf32 => "truncf",
8686
sym::truncf64 => "trunc",
87-
sym::rintf32 => "rintf",
88-
sym::rintf64 => "rint",
89-
sym::nearbyintf32 => "nearbyintf",
90-
sym::nearbyintf64 => "nearbyint",
87+
// We match the LLVM backend and lower this to `rint`.
88+
sym::round_ties_even_f32 => "rintf",
89+
sym::round_ties_even_f64 => "rint",
9190
sym::roundf32 => "roundf",
9291
sym::roundf64 => "round",
93-
sym::roundevenf32 => "roundevenf",
94-
sym::roundevenf64 => "roundeven",
9592
sym::abort => "abort",
9693
_ => return None,
9794
};

‎compiler/rustc_codegen_llvm/src/intrinsic.rs

+8-14
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,14 @@ fn get_simple_intrinsic<'ll>(
126126
sym::truncf64 => "llvm.trunc.f64",
127127
sym::truncf128 => "llvm.trunc.f128",
128128

129-
sym::rintf16 => "llvm.rint.f16",
130-
sym::rintf32 => "llvm.rint.f32",
131-
sym::rintf64 => "llvm.rint.f64",
132-
sym::rintf128 => "llvm.rint.f128",
133-
134-
sym::nearbyintf16 => "llvm.nearbyint.f16",
135-
sym::nearbyintf32 => "llvm.nearbyint.f32",
136-
sym::nearbyintf64 => "llvm.nearbyint.f64",
137-
sym::nearbyintf128 => "llvm.nearbyint.f128",
129+
// We could use any of `rint`, `nearbyint`, or `roundeven`
130+
// for this -- they are all identical in semantics when
131+
// assuming the default FP environment.
132+
// `rint` is what we used for $forever.
133+
sym::round_ties_even_f16 => "llvm.rint.f16",
134+
sym::round_ties_even_f32 => "llvm.rint.f32",
135+
sym::round_ties_even_f64 => "llvm.rint.f64",
136+
sym::round_ties_even_f128 => "llvm.rint.f128",
138137

139138
sym::roundf16 => "llvm.round.f16",
140139
sym::roundf32 => "llvm.round.f32",
@@ -143,11 +142,6 @@ fn get_simple_intrinsic<'ll>(
143142

144143
sym::ptr_mask => "llvm.ptrmask",
145144

146-
sym::roundevenf16 => "llvm.roundeven.f16",
147-
sym::roundevenf32 => "llvm.roundeven.f32",
148-
sym::roundevenf64 => "llvm.roundeven.f64",
149-
sym::roundevenf128 => "llvm.roundeven.f128",
150-
151145
_ => return None,
152146
};
153147
Some(cx.get_intrinsic(llvm_name))

‎compiler/rustc_hir_analysis/src/check/intrinsic.rs

+4-14
Original file line numberDiff line numberDiff line change
@@ -398,26 +398,16 @@ pub fn check_intrinsic_type(
398398
sym::truncf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
399399
sym::truncf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
400400

401-
sym::rintf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
402-
sym::rintf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
403-
sym::rintf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
404-
sym::rintf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
405-
406-
sym::nearbyintf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
407-
sym::nearbyintf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
408-
sym::nearbyintf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
409-
sym::nearbyintf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
401+
sym::round_ties_even_f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
402+
sym::round_ties_even_f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
403+
sym::round_ties_even_f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
404+
sym::round_ties_even_f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
410405

411406
sym::roundf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
412407
sym::roundf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
413408
sym::roundf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
414409
sym::roundf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
415410

416-
sym::roundevenf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
417-
sym::roundevenf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
418-
sym::roundevenf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
419-
sym::roundevenf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
420-
421411
sym::volatile_load | sym::unaligned_volatile_load => {
422412
(1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0))
423413
}

‎compiler/rustc_span/src/symbol.rs

+4-12
Original file line numberDiff line numberDiff line change
@@ -1337,10 +1337,6 @@ symbols! {
13371337
native_link_modifiers_whole_archive,
13381338
natvis_file,
13391339
ne,
1340-
nearbyintf128,
1341-
nearbyintf16,
1342-
nearbyintf32,
1343-
nearbyintf64,
13441340
needs_allocator,
13451341
needs_drop,
13461342
needs_panic_runtime,
@@ -1655,20 +1651,16 @@ symbols! {
16551651
return_position_impl_trait_in_trait,
16561652
return_type_notation,
16571653
rhs,
1658-
rintf128,
1659-
rintf16,
1660-
rintf32,
1661-
rintf64,
16621654
riscv_target_feature,
16631655
rlib,
16641656
ropi,
16651657
ropi_rwpi: "ropi-rwpi",
16661658
rotate_left,
16671659
rotate_right,
1668-
roundevenf128,
1669-
roundevenf16,
1670-
roundevenf32,
1671-
roundevenf64,
1660+
round_ties_even_f128,
1661+
round_ties_even_f16,
1662+
round_ties_even_f32,
1663+
round_ties_even_f64,
16721664
roundf128,
16731665
roundf16,
16741666
roundf32,

‎library/core/src/intrinsics/mod.rs

+73-112
Original file line numberDiff line numberDiff line change
@@ -2739,110 +2739,112 @@ pub unsafe fn truncf128(_x: f128) -> f128 {
27392739
unreachable!()
27402740
}
27412741

2742-
/// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust,
2743-
/// so this rounds half-way cases to the number with an even least significant digit.
2744-
///
2745-
/// May raise an inexact floating-point exception if the argument is not an integer.
2746-
/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
2747-
/// cannot actually be utilized from Rust code.
2748-
/// In other words, this intrinsic is equivalent in behavior to `nearbyintf16` and `roundevenf16`.
2742+
/// Returns the nearest integer to an `f16`. Rounds half-way cases to the number with an even
2743+
/// least significant digit.
27492744
///
27502745
/// The stabilized version of this intrinsic is
27512746
/// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even)
27522747
#[rustc_intrinsic]
27532748
#[rustc_intrinsic_must_be_overridden]
27542749
#[rustc_nounwind]
2755-
pub unsafe fn rintf16(_x: f16) -> f16 {
2750+
#[cfg(not(bootstrap))]
2751+
pub unsafe fn round_ties_even_f16(_x: f16) -> f16 {
27562752
unreachable!()
27572753
}
2758-
/// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust,
2759-
/// so this rounds half-way cases to the number with an even least significant digit.
2760-
///
2761-
/// May raise an inexact floating-point exception if the argument is not an integer.
2762-
/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
2763-
/// cannot actually be utilized from Rust code.
2764-
/// In other words, this intrinsic is equivalent in behavior to `nearbyintf32` and `roundevenf32`.
2754+
2755+
/// To be removed on next bootstrap bump.
2756+
#[cfg(bootstrap)]
2757+
pub unsafe fn round_ties_even_f16(x: f16) -> f16 {
2758+
#[rustc_intrinsic]
2759+
#[rustc_intrinsic_must_be_overridden]
2760+
#[rustc_nounwind]
2761+
unsafe fn rintf16(_x: f16) -> f16 {
2762+
unreachable!()
2763+
}
2764+
2765+
// SAFETY: this intrinsic isn't actually unsafe
2766+
unsafe { rintf16(x) }
2767+
}
2768+
2769+
/// Returns the nearest integer to an `f32`. Rounds half-way cases to the number with an even
2770+
/// least significant digit.
27652771
///
27662772
/// The stabilized version of this intrinsic is
27672773
/// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even)
27682774
#[rustc_intrinsic]
27692775
#[rustc_intrinsic_must_be_overridden]
27702776
#[rustc_nounwind]
2771-
pub unsafe fn rintf32(_x: f32) -> f32 {
2777+
#[cfg(not(bootstrap))]
2778+
pub unsafe fn round_ties_even_f32(_x: f32) -> f32 {
27722779
unreachable!()
27732780
}
2774-
/// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust,
2775-
/// so this rounds half-way cases to the number with an even least significant digit.
2776-
///
2777-
/// May raise an inexact floating-point exception if the argument is not an integer.
2778-
/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
2779-
/// cannot actually be utilized from Rust code.
2780-
/// In other words, this intrinsic is equivalent in behavior to `nearbyintf64` and `roundevenf64`.
2781+
2782+
/// To be removed on next bootstrap bump.
2783+
#[cfg(bootstrap)]
2784+
pub unsafe fn round_ties_even_f32(x: f32) -> f32 {
2785+
#[rustc_intrinsic]
2786+
#[rustc_intrinsic_must_be_overridden]
2787+
#[rustc_nounwind]
2788+
unsafe fn rintf32(_x: f32) -> f32 {
2789+
unreachable!()
2790+
}
2791+
2792+
// SAFETY: this intrinsic isn't actually unsafe
2793+
unsafe { rintf32(x) }
2794+
}
2795+
2796+
/// Returns the nearest integer to an `f64`. Rounds half-way cases to the number with an even
2797+
/// least significant digit.
27812798
///
27822799
/// The stabilized version of this intrinsic is
27832800
/// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even)
27842801
#[rustc_intrinsic]
27852802
#[rustc_intrinsic_must_be_overridden]
27862803
#[rustc_nounwind]
2787-
pub unsafe fn rintf64(_x: f64) -> f64 {
2804+
#[cfg(not(bootstrap))]
2805+
pub unsafe fn round_ties_even_f64(_x: f64) -> f64 {
27882806
unreachable!()
27892807
}
2790-
/// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust,
2791-
/// so this rounds half-way cases to the number with an even least significant digit.
2792-
///
2793-
/// May raise an inexact floating-point exception if the argument is not an integer.
2794-
/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
2795-
/// cannot actually be utilized from Rust code.
2796-
/// In other words, this intrinsic is equivalent in behavior to `nearbyintf128` and `roundevenf128`.
2808+
2809+
/// To be removed on next bootstrap bump.
2810+
#[cfg(bootstrap)]
2811+
pub unsafe fn round_ties_even_f64(x: f64) -> f64 {
2812+
#[rustc_intrinsic]
2813+
#[rustc_intrinsic_must_be_overridden]
2814+
#[rustc_nounwind]
2815+
unsafe fn rintf64(_x: f64) -> f64 {
2816+
unreachable!()
2817+
}
2818+
2819+
// SAFETY: this intrinsic isn't actually unsafe
2820+
unsafe { rintf64(x) }
2821+
}
2822+
2823+
/// Returns the nearest integer to an `f128`. Rounds half-way cases to the number with an even
2824+
/// least significant digit.
27972825
///
27982826
/// The stabilized version of this intrinsic is
27992827
/// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even)
28002828
#[rustc_intrinsic]
28012829
#[rustc_intrinsic_must_be_overridden]
28022830
#[rustc_nounwind]
2803-
pub unsafe fn rintf128(_x: f128) -> f128 {
2831+
#[cfg(not(bootstrap))]
2832+
pub unsafe fn round_ties_even_f128(_x: f128) -> f128 {
28042833
unreachable!()
28052834
}
28062835

2807-
/// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust,
2808-
/// so this rounds half-way cases to the number with an even least significant digit.
2809-
///
2810-
/// This intrinsic does not have a stable counterpart.
2811-
#[rustc_intrinsic]
2812-
#[rustc_intrinsic_must_be_overridden]
2813-
#[rustc_nounwind]
2814-
pub unsafe fn nearbyintf16(_x: f16) -> f16 {
2815-
unreachable!()
2816-
}
2817-
/// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust,
2818-
/// so this rounds half-way cases to the number with an even least significant digit.
2819-
///
2820-
/// This intrinsic does not have a stable counterpart.
2821-
#[rustc_intrinsic]
2822-
#[rustc_intrinsic_must_be_overridden]
2823-
#[rustc_nounwind]
2824-
pub unsafe fn nearbyintf32(_x: f32) -> f32 {
2825-
unreachable!()
2826-
}
2827-
/// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust,
2828-
/// so this rounds half-way cases to the number with an even least significant digit.
2829-
///
2830-
/// This intrinsic does not have a stable counterpart.
2831-
#[rustc_intrinsic]
2832-
#[rustc_intrinsic_must_be_overridden]
2833-
#[rustc_nounwind]
2834-
pub unsafe fn nearbyintf64(_x: f64) -> f64 {
2835-
unreachable!()
2836-
}
2837-
/// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust,
2838-
/// so this rounds half-way cases to the number with an even least significant digit.
2839-
///
2840-
/// This intrinsic does not have a stable counterpart.
2841-
#[rustc_intrinsic]
2842-
#[rustc_intrinsic_must_be_overridden]
2843-
#[rustc_nounwind]
2844-
pub unsafe fn nearbyintf128(_x: f128) -> f128 {
2845-
unreachable!()
2836+
/// To be removed on next bootstrap bump.
2837+
#[cfg(bootstrap)]
2838+
pub unsafe fn round_ties_even_f128(x: f128) -> f128 {
2839+
#[rustc_intrinsic]
2840+
#[rustc_intrinsic_must_be_overridden]
2841+
#[rustc_nounwind]
2842+
unsafe fn rintf128(_x: f128) -> f128 {
2843+
unreachable!()
2844+
}
2845+
2846+
// SAFETY: this intrinsic isn't actually unsafe
2847+
unsafe { rintf128(x) }
28462848
}
28472849

28482850
/// 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 {
28862888
unreachable!()
28872889
}
28882890

2889-
/// Returns the nearest integer to an `f16`. Rounds half-way cases to the number
2890-
/// with an even least significant digit.
2891-
///
2892-
/// This intrinsic does not have a stable counterpart.
2893-
#[rustc_intrinsic]
2894-
#[rustc_intrinsic_must_be_overridden]
2895-
#[rustc_nounwind]
2896-
pub unsafe fn roundevenf16(_x: f16) -> f16 {
2897-
unreachable!()
2898-
}
2899-
/// Returns the nearest integer to an `f32`. Rounds half-way cases to the number
2900-
/// with an even least significant digit.
2901-
///
2902-
/// This intrinsic does not have a stable counterpart.
2903-
#[rustc_intrinsic]
2904-
#[rustc_intrinsic_must_be_overridden]
2905-
#[rustc_nounwind]
2906-
pub unsafe fn roundevenf32(_x: f32) -> f32 {
2907-
unreachable!()
2908-
}
2909-
/// Returns the nearest integer to an `f64`. Rounds half-way cases to the number
2910-
/// with an even least significant digit.
2911-
///
2912-
/// This intrinsic does not have a stable counterpart.
2913-
#[rustc_intrinsic]
2914-
#[rustc_intrinsic_must_be_overridden]
2915-
#[rustc_nounwind]
2916-
pub unsafe fn roundevenf64(_x: f64) -> f64 {
2917-
unreachable!()
2918-
}
2919-
/// Returns the nearest integer to an `f128`. Rounds half-way cases to the number
2920-
/// with an even least significant digit.
2921-
///
2922-
/// This intrinsic does not have a stable counterpart.
2923-
#[rustc_intrinsic]
2924-
#[rustc_intrinsic_must_be_overridden]
2925-
#[rustc_nounwind]
2926-
pub unsafe fn roundevenf128(_x: f128) -> f128 {
2927-
unreachable!()
2928-
}
2929-
29302891
/// Float addition that allows optimizations based on algebraic rules.
29312892
/// May assume inputs are finite.
29322893
///

0 commit comments

Comments
 (0)
Please sign in to comment.