Skip to content

Commit a69c441

Browse files
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.
2 parents 3aec4a2 + 3d9bbf9 commit a69c441

File tree

4 files changed

+17
-113
lines changed

4 files changed

+17
-113
lines changed

.github/workflows/ci.yml

+1-2
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,7 @@ jobs:
121121
# for NaNs which makes it worth testing on despite that.
122122
- mips-unknown-linux-gnu
123123
- mips64-unknown-linux-gnuabi64
124-
# TODO: reenable pending https://github.com/rust-lang/rust/issues/77866
125-
# - riscv64gc-unknown-linux-gnu
124+
- riscv64gc-unknown-linux-gnu
126125

127126
steps:
128127
- uses: actions/checkout@v2

crates/core_simd/src/intrinsics.rs

+6
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,10 @@ extern "platform-intrinsic" {
3939

4040
/// fptoui/fptosi/uitofp/sitofp
4141
pub(crate) fn simd_cast<T, U>(x: T) -> U;
42+
43+
// floor
44+
pub(crate) fn simd_floor<T>(x: T) -> T;
45+
46+
// ceil
47+
pub(crate) fn simd_ceil<T>(x: T) -> T;
4248
}

crates/core_simd/src/round.rs

+10-75
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,23 @@
11
macro_rules! implement {
22
{
33
impl $type:ident {
4-
int_type = $int_type:ident,
5-
floor = $floor_intrinsic:literal,
6-
ceil = $ceil_intrinsic:literal,
7-
round = $round_intrinsic:literal,
8-
trunc = $trunc_intrinsic:literal,
4+
int_type = $int_type:ident
95
}
106
} => {
117
mod $type {
12-
#[allow(improper_ctypes)]
13-
extern "C" {
14-
#[link_name = $floor_intrinsic]
15-
fn floor_intrinsic(x: crate::$type) -> crate::$type;
16-
#[link_name = $ceil_intrinsic]
17-
fn ceil_intrinsic(x: crate::$type) -> crate::$type;
18-
#[link_name = $round_intrinsic]
19-
fn round_intrinsic(x: crate::$type) -> crate::$type;
20-
#[link_name = $trunc_intrinsic]
21-
fn trunc_intrinsic(x: crate::$type) -> crate::$type;
22-
}
23-
248
impl crate::$type {
259
/// Returns the largest integer less than or equal to each lane.
2610
#[must_use = "method returns a new vector and does not mutate the original value"]
2711
#[inline]
2812
pub fn floor(self) -> Self {
29-
unsafe { floor_intrinsic(self) }
13+
unsafe { crate::intrinsics::simd_floor(self) }
3014
}
3115

3216
/// Returns the smallest integer greater than or equal to each lane.
3317
#[must_use = "method returns a new vector and does not mutate the original value"]
3418
#[inline]
3519
pub fn ceil(self) -> Self {
36-
unsafe { ceil_intrinsic(self) }
37-
}
38-
39-
/// Returns the nearest integer to each lane. Round half-way cases away from 0.0.
40-
#[must_use = "method returns a new vector and does not mutate the original value"]
41-
#[inline]
42-
pub fn round(self) -> Self {
43-
unsafe { round_intrinsic(self) }
44-
}
45-
46-
/// Returns the integer part of each lane.
47-
#[must_use = "method returns a new vector and does not mutate the original value"]
48-
#[inline]
49-
pub fn trunc(self) -> Self {
50-
unsafe { trunc_intrinsic(self) }
51-
}
52-
53-
/// Returns the fractional part of each lane.
54-
#[must_use = "method returns a new vector and does not mutate the original value"]
55-
#[inline]
56-
pub fn fract(self) -> Self {
57-
self - self.trunc()
20+
unsafe { crate::intrinsics::simd_ceil(self) }
5821
}
5922

6023
/// Rounds toward zero and converts to the same-width integer type, assuming that
@@ -84,70 +47,42 @@ macro_rules! implement {
8447

8548
implement! {
8649
impl f32x2 {
87-
int_type = i32x2,
88-
floor = "llvm.floor.v2f32",
89-
ceil = "llvm.ceil.v2f32",
90-
round = "llvm.round.v2f32",
91-
trunc = "llvm.trunc.v2f32",
50+
int_type = i32x2
9251
}
9352
}
9453

9554
implement! {
9655
impl f32x4 {
97-
int_type = i32x4,
98-
floor = "llvm.floor.v4f32",
99-
ceil = "llvm.ceil.v4f32",
100-
round = "llvm.round.v4f32",
101-
trunc = "llvm.trunc.v4f32",
56+
int_type = i32x4
10257
}
10358
}
10459

10560
implement! {
10661
impl f32x8 {
107-
int_type = i32x8,
108-
floor = "llvm.floor.v8f32",
109-
ceil = "llvm.ceil.v8f32",
110-
round = "llvm.round.v8f32",
111-
trunc = "llvm.trunc.v8f32",
62+
int_type = i32x8
11263
}
11364
}
11465

11566
implement! {
11667
impl f32x16 {
117-
int_type = i32x16,
118-
floor = "llvm.floor.v16f32",
119-
ceil = "llvm.ceil.v16f32",
120-
round = "llvm.round.v16f32",
121-
trunc = "llvm.trunc.v16f32",
68+
int_type = i32x16
12269
}
12370
}
12471

12572
implement! {
12673
impl f64x2 {
127-
int_type = i64x2,
128-
floor = "llvm.floor.v2f64",
129-
ceil = "llvm.ceil.v2f64",
130-
round = "llvm.round.v2f64",
131-
trunc = "llvm.trunc.v2f64",
74+
int_type = i64x2
13275
}
13376
}
13477

13578
implement! {
13679
impl f64x4 {
137-
int_type = i64x4,
138-
floor = "llvm.floor.v4f64",
139-
ceil = "llvm.ceil.v4f64",
140-
round = "llvm.round.v4f64",
141-
trunc = "llvm.trunc.v4f64",
80+
int_type = i64x4
14281
}
14382
}
14483

14584
implement! {
14685
impl f64x8 {
147-
int_type = i64x8,
148-
floor = "llvm.floor.v8f64",
149-
ceil = "llvm.ceil.v8f64",
150-
round = "llvm.round.v8f64",
151-
trunc = "llvm.trunc.v8f64",
86+
int_type = i64x8
15287
}
15388
}

crates/core_simd/tests/ops_impl/float_macros.rs

-36
Original file line numberDiff line numberDiff line change
@@ -353,42 +353,6 @@ macro_rules! float_tests {
353353
}
354354
}
355355

356-
#[test]
357-
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
358-
fn round_odd_floats() {
359-
for v in slice_chunks(&C) {
360-
let expected = apply_unary_lanewise(v, <$scalar>::round);
361-
assert_biteq!(v.round(), expected);
362-
}
363-
}
364-
365-
#[test]
366-
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
367-
fn round_mode() {
368-
assert_biteq!(core_simd::$vector::splat(1.5).round(), core_simd::$vector::splat(2.0));
369-
assert_biteq!(core_simd::$vector::splat(2.5).round(), core_simd::$vector::splat(3.0));
370-
assert_biteq!(core_simd::$vector::splat(-1.5).round(), core_simd::$vector::splat(-2.0));
371-
assert_biteq!(core_simd::$vector::splat(-2.5).round(), core_simd::$vector::splat(-3.0));
372-
}
373-
374-
#[test]
375-
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
376-
fn trunc_odd_floats() {
377-
for v in slice_chunks(&C) {
378-
let expected = apply_unary_lanewise(v, <$scalar>::trunc);
379-
assert_biteq!(v.trunc(), expected);
380-
}
381-
}
382-
383-
#[test]
384-
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
385-
fn fract_odd_floats() {
386-
for v in slice_chunks(&C) {
387-
let expected = apply_unary_lanewise(v, <$scalar>::fract);
388-
assert_biteq!(v.fract(), expected);
389-
}
390-
}
391-
392356
#[test]
393357
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
394358
fn to_int_unchecked() {

0 commit comments

Comments
 (0)