Use core::arch::wasm functions rather than intrinsics

These wasm functions are available in `core::arch::wasm32` since [1], so
we can use them while avoiding the possibly-recursive `intrinsics::*`
calls (in practice none of those should always lower to libcalls on
wasm, but that is up to LLVM).

Since these require an unstable feature, they are still gated under
`unstable-intrinsics`.

[1]: https://github.com/rust-lang/stdarch/pull/1677
This commit is contained in:
Trevor Gross 2025-01-11 21:24:06 +00:00 committed by Trevor Gross
parent a0c03b2537
commit ab1038a32b
2 changed files with 11 additions and 20 deletions

View file

@ -2,6 +2,7 @@
#![no_std]
#![cfg_attr(intrinsics_enabled, allow(internal_features))]
#![cfg_attr(intrinsics_enabled, feature(core_intrinsics))]
#![cfg_attr(all(intrinsics_enabled, target_family = "wasm"), feature(wasm_numeric_instr))]
#![cfg_attr(f128_enabled, feature(f128))]
#![cfg_attr(f16_enabled, feature(f16))]
#![allow(clippy::assign_op_pattern)]

View file

@ -1,16 +1,12 @@
//! Wasm asm is not stable; just use intrinsics for operations that have asm routine equivalents.
//!
//! Note that we need to be absolutely certain that everything here lowers to assembly operations,
//! otherwise libcalls will be recursive.
//! Wasm has builtins for simple float operations. Use the unstable `core::arch` intrinsics which
//! are significantly faster than soft float operations.
pub fn ceil(x: f64) -> f64 {
// SAFETY: safe intrinsic with no preconditions
unsafe { core::intrinsics::ceilf64(x) }
core::arch::wasm32::f64_ceil(x)
}
pub fn ceilf(x: f32) -> f32 {
// SAFETY: safe intrinsic with no preconditions
unsafe { core::intrinsics::ceilf32(x) }
core::arch::wasm32::f32_ceil(x)
}
pub fn fabs(x: f64) -> f64 {
@ -22,31 +18,25 @@ pub fn fabsf(x: f32) -> f32 {
}
pub fn floor(x: f64) -> f64 {
// SAFETY: safe intrinsic with no preconditions
unsafe { core::intrinsics::floorf64(x) }
core::arch::wasm32::f64_floor(x)
}
pub fn floorf(x: f32) -> f32 {
// SAFETY: safe intrinsic with no preconditions
unsafe { core::intrinsics::floorf32(x) }
core::arch::wasm32::f32_floor(x)
}
pub fn sqrt(x: f64) -> f64 {
// SAFETY: safe intrinsic with no preconditions
unsafe { core::intrinsics::sqrtf64(x) }
core::arch::wasm32::f64_sqrt(x)
}
pub fn sqrtf(x: f32) -> f32 {
// SAFETY: safe intrinsic with no preconditions
unsafe { core::intrinsics::sqrtf32(x) }
core::arch::wasm32::f32_sqrt(x)
}
pub fn trunc(x: f64) -> f64 {
// SAFETY: safe intrinsic with no preconditions
unsafe { core::intrinsics::truncf64(x) }
core::arch::wasm32::f64_trunc(x)
}
pub fn truncf(x: f32) -> f32 {
// SAFETY: safe intrinsic with no preconditions
unsafe { core::intrinsics::truncf32(x) }
core::arch::wasm32::f32_trunc(x)
}