Skip to content

Commit 5e9ded4

Browse files
authored
Merge pull request rust-lang#437 from tgross35/generic-floor
Add `floorf16` and `floorf128`
2 parents 812e15a + 31f0802 commit 5e9ded4

File tree

17 files changed

+175
-100
lines changed

17 files changed

+175
-100
lines changed

crates/compiler-builtins-smoke-test/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ no_mangle! {
6767
cbrtf(x: f32) -> f32;
6868
ceil(x: f64) -> f64;
6969
ceilf(x: f32) -> f32;
70+
ceilf128(x: f128) -> f128;
71+
ceilf16(x: f16) -> f16;
7072
copysign(x: f64, y: f64) -> f64;
7173
copysignf(x: f32, y: f32) -> f32;
7274
copysignf128(x: f128, y: f128) -> f128;
@@ -97,6 +99,8 @@ no_mangle! {
9799
fdimf16(x: f16, y: f16) -> f16;
98100
floor(x: f64) -> f64;
99101
floorf(x: f32) -> f32;
102+
floorf128(x: f128) -> f128;
103+
floorf16(x: f16) -> f16;
100104
fma(x: f64, y: f64, z: f64) -> f64;
101105
fmaf(x: f32, y: f32, z: f32) -> f32;
102106
fmax(x: f64, y: f64) -> f64;

crates/libm-macros/src/shared.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
99
FloatTy::F16,
1010
Signature { args: &[Ty::F16], returns: &[Ty::F16] },
1111
None,
12-
&["ceilf16", "fabsf16", "sqrtf16", "truncf16"],
12+
&["ceilf16", "fabsf16", "floorf16", "sqrtf16", "truncf16"],
1313
),
1414
(
1515
// `fn(f32) -> f32`
@@ -40,7 +40,7 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
4040
FloatTy::F128,
4141
Signature { args: &[Ty::F128], returns: &[Ty::F128] },
4242
None,
43-
&["ceilf128", "fabsf128", "sqrtf128", "truncf128"],
43+
&["ceilf128", "fabsf128", "floorf128", "sqrtf128", "truncf128"],
4444
),
4545
(
4646
// `(f16, f16) -> f16`

crates/libm-test/benches/icount.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ main!(
101101
icount_bench_fdimf16_group,
102102
icount_bench_fdimf_group,
103103
icount_bench_floor_group,
104+
icount_bench_floorf128_group,
105+
icount_bench_floorf16_group,
104106
icount_bench_floorf_group,
105107
icount_bench_fma_group,
106108
icount_bench_fmaf_group,

crates/libm-test/benches/random.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,10 @@ libm_macros::for_each_function! {
125125
| fabsf16
126126
| fdimf128
127127
| fdimf16
128-
| sqrtf16
128+
| floorf128
129+
| floorf16
129130
| sqrtf128
131+
| sqrtf16
130132
| truncf128
131133
| truncf16 => (false, None),
132134

crates/libm-test/src/mpfloat.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ libm_macros::for_each_function! {
148148
fabsf128,
149149
fabsf16,floor,
150150
floorf,
151+
floorf128,
152+
floorf16,
151153
fmod,
152154
fmodf,
153155
frexp,
@@ -240,13 +242,15 @@ impl_no_round! {
240242
impl_no_round! {
241243
fabsf16 => abs_mut;
242244
ceilf16 => ceil_mut;
245+
floorf16 => floor_mut;
243246
truncf16 => trunc_mut;
244247
}
245248

246249
#[cfg(f128_enabled)]
247250
impl_no_round! {
248251
fabsf128 => abs_mut;
249252
ceilf128 => ceil_mut;
253+
floorf128 => floor_mut;
250254
truncf128 => trunc_mut;
251255
}
252256

crates/libm-test/tests/compare_built_musl.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ libm_macros::for_each_function! {
8787
fabsf16,
8888
fdimf128,
8989
fdimf16,
90+
floorf128,
91+
floorf16,
9092
truncf128,
9193
truncf16,
9294
sqrtf16,

crates/util/src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ fn do_eval(basis: &str, op: &str, inputs: &[&str]) {
9292
| fabsf16
9393
| fdimf128
9494
| fdimf16
95+
| floorf128
96+
| floorf16
9597
| sqrtf128
9698
| sqrtf16
9799
| truncf128

etc/function-definitions.json

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,17 +336,33 @@
336336
"src/libm_helper.rs",
337337
"src/math/arch/i586.rs",
338338
"src/math/arch/wasm32.rs",
339-
"src/math/floor.rs"
339+
"src/math/floor.rs",
340+
"src/math/generic/floor.rs"
340341
],
341342
"type": "f64"
342343
},
343344
"floorf": {
344345
"sources": [
345346
"src/math/arch/wasm32.rs",
346-
"src/math/floorf.rs"
347+
"src/math/floorf.rs",
348+
"src/math/generic/floor.rs"
347349
],
348350
"type": "f32"
349351
},
352+
"floorf128": {
353+
"sources": [
354+
"src/math/floorf128.rs",
355+
"src/math/generic/floor.rs"
356+
],
357+
"type": "f128"
358+
},
359+
"floorf16": {
360+
"sources": [
361+
"src/math/floorf16.rs",
362+
"src/math/generic/floor.rs"
363+
],
364+
"type": "f16"
365+
},
350366
"fma": {
351367
"sources": [
352368
"src/libm_helper.rs",

etc/function-list.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ fdimf128
4949
fdimf16
5050
floor
5151
floorf
52+
floorf128
53+
floorf16
5254
fma
5355
fmaf
5456
fmax

src/math/floor.rs

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
#![allow(unreachable_code)]
2-
use core::f64;
3-
4-
const TOINT: f64 = 1. / f64::EPSILON;
5-
61
/// Floor (f64)
72
///
83
/// Finds the nearest integer less than or equal to `x`.
@@ -15,39 +10,5 @@ pub fn floor(x: f64) -> f64 {
1510
args: x,
1611
}
1712

18-
let ui = x.to_bits();
19-
let e = ((ui >> 52) & 0x7ff) as i32;
20-
21-
if (e >= 0x3ff + 52) || (x == 0.) {
22-
return x;
23-
}
24-
/* y = int(x) - x, where int(x) is an integer neighbor of x */
25-
let y = if (ui >> 63) != 0 { x - TOINT + TOINT - x } else { x + TOINT - TOINT - x };
26-
/* special case because of non-nearest rounding modes */
27-
if e < 0x3ff {
28-
force_eval!(y);
29-
return if (ui >> 63) != 0 { -1. } else { 0. };
30-
}
31-
if y > 0. { x + y - 1. } else { x + y }
32-
}
33-
34-
#[cfg(test)]
35-
mod tests {
36-
use super::*;
37-
38-
#[test]
39-
fn sanity_check() {
40-
assert_eq!(floor(1.1), 1.0);
41-
assert_eq!(floor(2.9), 2.0);
42-
}
43-
44-
/// The spec: https://en.cppreference.com/w/cpp/numeric/math/floor
45-
#[test]
46-
fn spec_tests() {
47-
// Not Asserted: that the current rounding mode has no effect.
48-
assert!(floor(f64::NAN).is_nan());
49-
for f in [0.0, -0.0, f64::INFINITY, f64::NEG_INFINITY].iter().copied() {
50-
assert_eq!(floor(f), f);
51-
}
52-
}
13+
return super::generic::floor(x);
5314
}

src/math/floorf.rs

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use core::f32;
2-
31
/// Floor (f32)
42
///
53
/// Finds the nearest integer less than or equal to `x`.
@@ -11,53 +9,5 @@ pub fn floorf(x: f32) -> f32 {
119
args: x,
1210
}
1311

14-
let mut ui = x.to_bits();
15-
let e = (((ui >> 23) as i32) & 0xff) - 0x7f;
16-
17-
if e >= 23 {
18-
return x;
19-
}
20-
if e >= 0 {
21-
let m: u32 = 0x007fffff >> e;
22-
if (ui & m) == 0 {
23-
return x;
24-
}
25-
force_eval!(x + f32::from_bits(0x7b800000));
26-
if ui >> 31 != 0 {
27-
ui += m;
28-
}
29-
ui &= !m;
30-
} else {
31-
force_eval!(x + f32::from_bits(0x7b800000));
32-
if ui >> 31 == 0 {
33-
ui = 0;
34-
} else if ui << 1 != 0 {
35-
return -1.0;
36-
}
37-
}
38-
f32::from_bits(ui)
39-
}
40-
41-
// PowerPC tests are failing on LLVM 13: https://github.com/rust-lang/rust/issues/88520
42-
#[cfg(not(target_arch = "powerpc64"))]
43-
#[cfg(test)]
44-
mod tests {
45-
use super::*;
46-
47-
#[test]
48-
fn sanity_check() {
49-
assert_eq!(floorf(0.5), 0.0);
50-
assert_eq!(floorf(1.1), 1.0);
51-
assert_eq!(floorf(2.9), 2.0);
52-
}
53-
54-
/// The spec: https://en.cppreference.com/w/cpp/numeric/math/floor
55-
#[test]
56-
fn spec_tests() {
57-
// Not Asserted: that the current rounding mode has no effect.
58-
assert!(floorf(f32::NAN).is_nan());
59-
for f in [0.0, -0.0, f32::INFINITY, f32::NEG_INFINITY].iter().copied() {
60-
assert_eq!(floorf(f), f);
61-
}
62-
}
12+
return super::generic::floor(x);
6313
}

src/math/floorf128.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/// Floor (f128)
2+
///
3+
/// Finds the nearest integer less than or equal to `x`.
4+
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
5+
pub fn floorf128(x: f128) -> f128 {
6+
return super::generic::floor(x);
7+
}

src/math/floorf16.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/// Floor (f16)
2+
///
3+
/// Finds the nearest integer less than or equal to `x`.
4+
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
5+
pub fn floorf16(x: f16) -> f16 {
6+
return super::generic::floor(x);
7+
}

src/math/generic/ceil.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,28 @@ pub fn ceil<F: Float>(x: F) -> F {
3131

3232
// Otherwise, raise an inexact exception.
3333
force_eval!(x + F::MAX);
34+
3435
if x.is_sign_positive() {
3536
ix += m;
3637
}
38+
3739
ix &= !m;
40+
F::from_bits(ix)
3841
} else {
3942
// |x| < 1.0, raise an inexact exception since truncation will happen (unless x == 0).
4043
force_eval!(x + F::MAX);
4144

4245
if x.is_sign_negative() {
4346
// -1.0 < x <= -0.0; rounding up goes toward -0.0.
44-
return F::NEG_ZERO;
47+
F::NEG_ZERO
4548
} else if ix << 1 != zero {
4649
// 0.0 < x < 1.0; rounding up goes toward +1.0.
47-
return F::ONE;
50+
F::ONE
51+
} else {
52+
// +0.0 remains unchanged
53+
x
4854
}
4955
}
50-
51-
F::from_bits(ix)
5256
}
5357

5458
#[cfg(test)]

0 commit comments

Comments
 (0)