From 2ffa1dd392c1fe9c23a2f11f7b7a293a744c05ce Mon Sep 17 00:00:00 2001 From: sayantn Date: Thu, 5 Jun 2025 20:41:41 +0530 Subject: [PATCH] Implement `simd_round_ties_even` for miri, cg_clif and cg_gcc --- compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs | 5 ++++- compiler/rustc_codegen_gcc/src/intrinsic/simd.rs | 2 ++ src/tools/miri/src/intrinsics/simd.rs | 2 ++ src/tools/miri/tests/pass/intrinsics/portable-simd.rs | 8 ++++++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 46a441488fa6..f928ad8bc021 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -495,7 +495,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( | sym::simd_flog | sym::simd_flog10 | sym::simd_flog2 - | sym::simd_round => { + | sym::simd_round + | sym::simd_round_ties_even => { intrinsic_args!(fx, args => (a); intrinsic); if !a.layout().ty.is_simd() { @@ -526,6 +527,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( (sym::simd_flog2, types::F64) => "log2", (sym::simd_round, types::F32) => "roundf", (sym::simd_round, types::F64) => "round", + (sym::simd_round_ties_even, types::F32) => "rintf", + (sym::simd_round_ties_even, types::F64) => "rint", _ => unreachable!("{:?}", intrinsic), }; fx.lib_call( diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 82ef0d0b13a4..18ba1ca3d77e 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -779,6 +779,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( sym::simd_fsin => "sin", sym::simd_fsqrt => "sqrt", sym::simd_round => "round", + sym::simd_round_ties_even => "rint", sym::simd_trunc => "trunc", _ => return_error!(InvalidMonomorphization::UnrecognizedIntrinsic { span, name }), }; @@ -826,6 +827,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( | sym::simd_fsin | sym::simd_fsqrt | sym::simd_round + | sym::simd_round_ties_even | sym::simd_trunc ) { return simd_simple_float_intrinsic(name, in_elem, in_ty, in_len, bx, span, args); diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs index dbe193bdbda8..da674d8022fe 100644 --- a/src/tools/miri/src/intrinsics/simd.rs +++ b/src/tools/miri/src/intrinsics/simd.rs @@ -37,6 +37,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "ceil" | "floor" | "round" + | "round_ties_even" | "trunc" | "fsqrt" | "fsin" @@ -72,6 +73,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "ceil" => Op::Round(rustc_apfloat::Round::TowardPositive), "floor" => Op::Round(rustc_apfloat::Round::TowardNegative), "round" => Op::Round(rustc_apfloat::Round::NearestTiesToAway), + "round_ties_even" => Op::Round(rustc_apfloat::Round::NearestTiesToEven), "trunc" => Op::Round(rustc_apfloat::Round::TowardZero), "ctlz" => Op::Numeric(sym::ctlz), "ctpop" => Op::Numeric(sym::ctpop), diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs index e14ce51f35a3..726d4c01cc3f 100644 --- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs +++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs @@ -569,6 +569,10 @@ fn simd_round() { f32x4::from_array([0.9, 1.001, 2.0, -4.5]).round(), f32x4::from_array([1.0, 1.0, 2.0, -5.0]) ); + assert_eq!( + unsafe { intrinsics::simd_round_ties_even(f32x4::from_array([0.9, 1.001, 2.0, -4.5])) }, + f32x4::from_array([1.0, 1.0, 2.0, -4.0]) + ); assert_eq!( f32x4::from_array([0.9, 1.001, 2.0, -4.5]).trunc(), f32x4::from_array([0.0, 1.0, 2.0, -4.0]) @@ -586,6 +590,10 @@ fn simd_round() { f64x4::from_array([0.9, 1.001, 2.0, -4.5]).round(), f64x4::from_array([1.0, 1.0, 2.0, -5.0]) ); + assert_eq!( + unsafe { intrinsics::simd_round_ties_even(f64x4::from_array([0.9, 1.001, 2.0, -4.5])) }, + f64x4::from_array([1.0, 1.0, 2.0, -4.0]) + ); assert_eq!( f64x4::from_array([0.9, 1.001, 2.0, -4.5]).trunc(), f64x4::from_array([0.0, 1.0, 2.0, -4.0])