From 4e5cbbeda169377e5025a979105d0dac31bf560a Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Wed, 9 Apr 2025 01:56:14 +0000 Subject: [PATCH] Replace calls to `core::arch` intrinsics with assembly Some backends may replace calls to `core::arch` with multiple calls to `sqrt` [1], which becomes recursive. Help mitigate this by replacing the call with assembly. Results in the same assembly as the current implementation when built with optimizations. [1]: https://github.com/rust-lang/compiler-builtins/issues/649 --- .../libm/src/math/arch/i686.rs | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/library/compiler-builtins/libm/src/math/arch/i686.rs b/library/compiler-builtins/libm/src/math/arch/i686.rs index ad54d8b61d77..3e1d19bfab69 100644 --- a/library/compiler-builtins/libm/src/math/arch/i686.rs +++ b/library/compiler-builtins/libm/src/math/arch/i686.rs @@ -1,22 +1,27 @@ //! Architecture-specific support for x86-32 and x86-64 with SSE2 -#[cfg(target_arch = "x86")] -use core::arch::x86::*; -#[cfg(target_arch = "x86_64")] -use core::arch::x86_64::*; - -pub fn sqrtf(x: f32) -> f32 { +pub fn sqrtf(mut x: f32) -> f32 { + // SAFETY: `sqrtss` is part of `sse2`, which this module is gated behind. It has no memory + // access or side effects. unsafe { - let m = _mm_set_ss(x); - let m_sqrt = _mm_sqrt_ss(m); - _mm_cvtss_f32(m_sqrt) - } + core::arch::asm!( + "sqrtss {x}, {x}", + x = inout(xmm_reg) x, + options(nostack, nomem, pure), + ) + }; + x } -pub fn sqrt(x: f64) -> f64 { +pub fn sqrt(mut x: f64) -> f64 { + // SAFETY: `sqrtsd` is part of `sse2`, which this module is gated behind. It has no memory + // access or side effects. unsafe { - let m = _mm_set_sd(x); - let m_sqrt = _mm_sqrt_pd(m); - _mm_cvtsd_f64(m_sqrt) - } + core::arch::asm!( + "sqrtsd {x}, {x}", + x = inout(xmm_reg) x, + options(nostack, nomem, pure), + ) + }; + x }