Make use of select_implementation

Replace all uses of `llvm_intrinsically` with select_implementation`.
This commit is contained in:
Trevor Gross 2024-10-28 19:38:19 -05:00
parent d54896343c
commit 60e7e3b338
11 changed files with 50 additions and 90 deletions

View file

@ -8,14 +8,12 @@ const TOINT: f64 = 1. / f64::EPSILON;
/// Finds the nearest integer greater than or equal to `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn ceil(x: f64) -> f64 {
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
// `f64.ceil` native instruction, so we can leverage this for both code size
// and speed.
llvm_intrinsically_optimized! {
#[cfg(target_arch = "wasm32")] {
return unsafe { ::core::intrinsics::ceilf64(x) }
}
select_implementation! {
name: ceil,
use_intrinsic: target_arch = "wasm32",
args: x,
}
#[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
{
//use an alternative implementation on x86, because the

View file

@ -5,14 +5,12 @@ use core::f32;
/// Finds the nearest integer greater than or equal to `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn ceilf(x: f32) -> f32 {
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
// `f32.ceil` native instruction, so we can leverage this for both code size
// and speed.
llvm_intrinsically_optimized! {
#[cfg(target_arch = "wasm32")] {
return unsafe { ::core::intrinsics::ceilf32(x) }
}
select_implementation! {
name: ceilf,
use_intrinsic: target_arch = "wasm32",
args: x,
}
let mut ui = x.to_bits();
let e = (((ui >> 23) & 0xff).wrapping_sub(0x7f)) as i32;

View file

@ -5,14 +5,12 @@ use core::u64;
/// by direct manipulation of the bit representation of `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn fabs(x: f64) -> f64 {
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
// `f64.abs` native instruction, so we can leverage this for both code size
// and speed.
llvm_intrinsically_optimized! {
#[cfg(target_arch = "wasm32")] {
return unsafe { ::core::intrinsics::fabsf64(x) }
}
select_implementation! {
name: fabs,
use_intrinsic: target_arch = "wasm32",
args: x,
}
f64::from_bits(x.to_bits() & (u64::MAX / 2))
}

View file

@ -3,14 +3,12 @@
/// by direct manipulation of the bit representation of `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn fabsf(x: f32) -> f32 {
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
// `f32.abs` native instruction, so we can leverage this for both code size
// and speed.
llvm_intrinsically_optimized! {
#[cfg(target_arch = "wasm32")] {
return unsafe { ::core::intrinsics::fabsf32(x) }
}
select_implementation! {
name: fabsf,
use_intrinsic: target_arch = "wasm32",
args: x,
}
f32::from_bits(x.to_bits() & 0x7fffffff)
}

View file

@ -8,14 +8,12 @@ const TOINT: f64 = 1. / f64::EPSILON;
/// Finds the nearest integer less than or equal to `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn floor(x: f64) -> f64 {
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
// `f64.floor` native instruction, so we can leverage this for both code size
// and speed.
llvm_intrinsically_optimized! {
#[cfg(target_arch = "wasm32")] {
return unsafe { ::core::intrinsics::floorf64(x) }
}
select_implementation! {
name: floor,
use_intrinsic: target_arch = "wasm32",
args: x,
}
#[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
{
//use an alternative implementation on x86, because the

View file

@ -5,14 +5,12 @@ use core::f32;
/// Finds the nearest integer less than or equal to `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn floorf(x: f32) -> f32 {
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
// `f32.floor` native instruction, so we can leverage this for both code size
// and speed.
llvm_intrinsically_optimized! {
#[cfg(target_arch = "wasm32")] {
return unsafe { ::core::intrinsics::floorf32(x) }
}
select_implementation! {
name: floorf,
use_intrinsic: target_arch = "wasm32",
args: x,
}
let mut ui = x.to_bits();
let e = (((ui >> 23) as i32) & 0xff) - 0x7f;

View file

@ -74,18 +74,6 @@ macro_rules! div {
};
}
// FIXME: phase this out, to be replaced by the more flexible `select_implementation`
macro_rules! llvm_intrinsically_optimized {
(#[cfg($($clause:tt)*)] $e:expr) => {
#[cfg(all(intrinsics_enabled, not(feature = "force-soft-floats"), $($clause)*))]
{
if true { // thwart the dead code lint
$e
}
}
};
}
// Private modules
#[macro_use]
mod support;

View file

@ -81,18 +81,12 @@ use core::f64;
/// The square root of `x` (f64).
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn sqrt(x: f64) -> f64 {
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
// `f64.sqrt` native instruction, so we can leverage this for both code size
// and speed.
llvm_intrinsically_optimized! {
#[cfg(target_arch = "wasm32")] {
return if x < 0.0 {
f64::NAN
} else {
unsafe { ::core::intrinsics::sqrtf64(x) }
}
}
select_implementation! {
name: sqrt,
use_intrinsic: target_arch = "wasm32",
args: x,
}
#[cfg(all(target_feature = "sse2", not(feature = "force-soft-floats")))]
{
// Note: This path is unlikely since LLVM will usually have already

View file

@ -16,18 +16,12 @@
/// The square root of `x` (f32).
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn sqrtf(x: f32) -> f32 {
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
// `f32.sqrt` native instruction, so we can leverage this for both code size
// and speed.
llvm_intrinsically_optimized! {
#[cfg(target_arch = "wasm32")] {
return if x < 0.0 {
::core::f32::NAN
} else {
unsafe { ::core::intrinsics::sqrtf32(x) }
}
}
select_implementation! {
name: sqrtf,
use_intrinsic: target_arch = "wasm32",
args: x,
}
#[cfg(all(target_feature = "sse", not(feature = "force-soft-floats")))]
{
// Note: This path is unlikely since LLVM will usually have already

View file

@ -2,14 +2,12 @@ use core::f64;
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn trunc(x: f64) -> f64 {
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
// `f64.trunc` native instruction, so we can leverage this for both code size
// and speed.
llvm_intrinsically_optimized! {
#[cfg(target_arch = "wasm32")] {
return unsafe { ::core::intrinsics::truncf64(x) }
}
select_implementation! {
name: trunc,
use_intrinsic: target_arch = "wasm32",
args: x,
}
let x1p120 = f64::from_bits(0x4770000000000000); // 0x1p120f === 2 ^ 120
let mut i: u64 = x.to_bits();

View file

@ -2,14 +2,12 @@ use core::f32;
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn truncf(x: f32) -> f32 {
// On wasm32 we know that LLVM's intrinsic will compile to an optimized
// `f32.trunc` native instruction, so we can leverage this for both code size
// and speed.
llvm_intrinsically_optimized! {
#[cfg(target_arch = "wasm32")] {
return unsafe { ::core::intrinsics::truncf32(x) }
}
select_implementation! {
name: truncf,
use_intrinsic: target_arch = "wasm32",
args: x,
}
let x1p120 = f32::from_bits(0x7b800000); // 0x1p120f === 2 ^ 120
let mut i: u32 = x.to_bits();