diff options
| author | Jubilee <46493976+workingjubilee@users.noreply.github.com> | 2020-12-08 15:42:48 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-12-08 15:42:48 -0800 |
| commit | a69c4414bc69d95d1ac1636cf2bc61deec21d936 (patch) | |
| tree | e8c0b4790f515f16aa70e2111618f1d991a4c3cb | |
| parent | 3aec4a2d00fab81b0372e3e98ea34d8305233f29 (diff) | |
| parent | 3d9bbf9b86f9f41d9ea5fe649343f3d763003866 (diff) | |
| download | rust-a69c4414bc69d95d1ac1636cf2bc61deec21d936.tar.gz rust-a69c4414bc69d95d1ac1636cf2bc61deec21d936.zip | |
Use platform intrinsics, not LLVM, for floor & ceil
This PR removes the direct linkage to LLVM for trunc and round intrinsics, while replacing that link with rustc's platform intrinsics for floor and ceil functions, namely simd_floor and simd_ceil. Tests that are no longer testable are removed. In doing so it resolves the riscv64gc compilation problems.
| -rw-r--r-- | .github/workflows/ci.yml | 3 | ||||
| -rw-r--r-- | crates/core_simd/src/intrinsics.rs | 6 | ||||
| -rw-r--r-- | crates/core_simd/src/round.rs | 85 | ||||
| -rw-r--r-- | crates/core_simd/tests/ops_impl/float_macros.rs | 36 |
4 files changed, 17 insertions, 113 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8d331257692..2104c74a4d9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -121,8 +121,7 @@ jobs: # for NaNs which makes it worth testing on despite that. - mips-unknown-linux-gnu - mips64-unknown-linux-gnuabi64 - # TODO: reenable pending https://github.com/rust-lang/rust/issues/77866 - # - riscv64gc-unknown-linux-gnu + - riscv64gc-unknown-linux-gnu steps: - uses: actions/checkout@v2 diff --git a/crates/core_simd/src/intrinsics.rs b/crates/core_simd/src/intrinsics.rs index acf85983a98..b2edc3747ef 100644 --- a/crates/core_simd/src/intrinsics.rs +++ b/crates/core_simd/src/intrinsics.rs @@ -39,4 +39,10 @@ extern "platform-intrinsic" { /// fptoui/fptosi/uitofp/sitofp pub(crate) fn simd_cast<T, U>(x: T) -> U; + + // floor + pub(crate) fn simd_floor<T>(x: T) -> T; + + // ceil + pub(crate) fn simd_ceil<T>(x: T) -> T; } diff --git a/crates/core_simd/src/round.rs b/crates/core_simd/src/round.rs index 021e5af8873..0529bbe0080 100644 --- a/crates/core_simd/src/round.rs +++ b/crates/core_simd/src/round.rs @@ -1,60 +1,23 @@ macro_rules! implement { { impl $type:ident { - int_type = $int_type:ident, - floor = $floor_intrinsic:literal, - ceil = $ceil_intrinsic:literal, - round = $round_intrinsic:literal, - trunc = $trunc_intrinsic:literal, + int_type = $int_type:ident } } => { mod $type { - #[allow(improper_ctypes)] - extern "C" { - #[link_name = $floor_intrinsic] - fn floor_intrinsic(x: crate::$type) -> crate::$type; - #[link_name = $ceil_intrinsic] - fn ceil_intrinsic(x: crate::$type) -> crate::$type; - #[link_name = $round_intrinsic] - fn round_intrinsic(x: crate::$type) -> crate::$type; - #[link_name = $trunc_intrinsic] - fn trunc_intrinsic(x: crate::$type) -> crate::$type; - } - impl crate::$type { /// Returns the largest integer less than or equal to each lane. #[must_use = "method returns a new vector and does not mutate the original value"] #[inline] pub fn floor(self) -> Self { - unsafe { floor_intrinsic(self) } + unsafe { crate::intrinsics::simd_floor(self) } } /// Returns the smallest integer greater than or equal to each lane. #[must_use = "method returns a new vector and does not mutate the original value"] #[inline] pub fn ceil(self) -> Self { - unsafe { ceil_intrinsic(self) } - } - - /// Returns the nearest integer to each lane. Round half-way cases away from 0.0. - #[must_use = "method returns a new vector and does not mutate the original value"] - #[inline] - pub fn round(self) -> Self { - unsafe { round_intrinsic(self) } - } - - /// Returns the integer part of each lane. - #[must_use = "method returns a new vector and does not mutate the original value"] - #[inline] - pub fn trunc(self) -> Self { - unsafe { trunc_intrinsic(self) } - } - - /// Returns the fractional part of each lane. - #[must_use = "method returns a new vector and does not mutate the original value"] - #[inline] - pub fn fract(self) -> Self { - self - self.trunc() + unsafe { crate::intrinsics::simd_ceil(self) } } /// Rounds toward zero and converts to the same-width integer type, assuming that @@ -84,70 +47,42 @@ macro_rules! implement { implement! { impl f32x2 { - int_type = i32x2, - floor = "llvm.floor.v2f32", - ceil = "llvm.ceil.v2f32", - round = "llvm.round.v2f32", - trunc = "llvm.trunc.v2f32", + int_type = i32x2 } } implement! { impl f32x4 { - int_type = i32x4, - floor = "llvm.floor.v4f32", - ceil = "llvm.ceil.v4f32", - round = "llvm.round.v4f32", - trunc = "llvm.trunc.v4f32", + int_type = i32x4 } } implement! { impl f32x8 { - int_type = i32x8, - floor = "llvm.floor.v8f32", - ceil = "llvm.ceil.v8f32", - round = "llvm.round.v8f32", - trunc = "llvm.trunc.v8f32", + int_type = i32x8 } } implement! { impl f32x16 { - int_type = i32x16, - floor = "llvm.floor.v16f32", - ceil = "llvm.ceil.v16f32", - round = "llvm.round.v16f32", - trunc = "llvm.trunc.v16f32", + int_type = i32x16 } } implement! { impl f64x2 { - int_type = i64x2, - floor = "llvm.floor.v2f64", - ceil = "llvm.ceil.v2f64", - round = "llvm.round.v2f64", - trunc = "llvm.trunc.v2f64", + int_type = i64x2 } } implement! { impl f64x4 { - int_type = i64x4, - floor = "llvm.floor.v4f64", - ceil = "llvm.ceil.v4f64", - round = "llvm.round.v4f64", - trunc = "llvm.trunc.v4f64", + int_type = i64x4 } } implement! { impl f64x8 { - int_type = i64x8, - floor = "llvm.floor.v8f64", - ceil = "llvm.ceil.v8f64", - round = "llvm.round.v8f64", - trunc = "llvm.trunc.v8f64", + int_type = i64x8 } } diff --git a/crates/core_simd/tests/ops_impl/float_macros.rs b/crates/core_simd/tests/ops_impl/float_macros.rs index 1f49aef9f12..fe347a5362d 100644 --- a/crates/core_simd/tests/ops_impl/float_macros.rs +++ b/crates/core_simd/tests/ops_impl/float_macros.rs @@ -355,42 +355,6 @@ macro_rules! float_tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn round_odd_floats() { - for v in slice_chunks(&C) { - let expected = apply_unary_lanewise(v, <$scalar>::round); - assert_biteq!(v.round(), expected); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn round_mode() { - assert_biteq!(core_simd::$vector::splat(1.5).round(), core_simd::$vector::splat(2.0)); - assert_biteq!(core_simd::$vector::splat(2.5).round(), core_simd::$vector::splat(3.0)); - assert_biteq!(core_simd::$vector::splat(-1.5).round(), core_simd::$vector::splat(-2.0)); - assert_biteq!(core_simd::$vector::splat(-2.5).round(), core_simd::$vector::splat(-3.0)); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn trunc_odd_floats() { - for v in slice_chunks(&C) { - let expected = apply_unary_lanewise(v, <$scalar>::trunc); - assert_biteq!(v.trunc(), expected); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn fract_odd_floats() { - for v in slice_chunks(&C) { - let expected = apply_unary_lanewise(v, <$scalar>::fract); - assert_biteq!(v.fract(), expected); - } - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn to_int_unchecked() { // The maximum integer that can be represented by the equivalently sized float has // all of the mantissa digits set to 1, pushed up to the MSB. |
