about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTrevor Gross <tmgross@umich.edu>2025-01-23 20:28:04 -0600
committerGitHub <noreply@github.com>2025-01-23 20:28:04 -0600
commit453bebf7c1fda9ff78a41d7739f0d930d1e27755 (patch)
tree81e57516cea0e13be71d2eeae62a6ca46eef2fa9
parent3aa2d1cfc2b47f23299bdf14214e2eb176482d05 (diff)
parent357ee34abbabd9742ff03013df9d764e0fffe8ab (diff)
downloadrust-453bebf7c1fda9ff78a41d7739f0d930d1e27755.tar.gz
rust-453bebf7c1fda9ff78a41d7739f0d930d1e27755.zip
Merge pull request rust-lang/libm#465 from tgross35/generic-round
Add `roundf16` and `roundf128`
-rw-r--r--library/compiler-builtins/libm/crates/libm-macros/src/shared.rs4
-rw-r--r--library/compiler-builtins/libm/crates/libm-test/benches/random.rs2
-rw-r--r--library/compiler-builtins/libm/crates/libm-test/src/mpfloat.rs4
-rw-r--r--library/compiler-builtins/libm/crates/libm-test/src/precision.rs3
-rw-r--r--library/compiler-builtins/libm/crates/libm-test/tests/compare_built_musl.rs2
-rw-r--r--library/compiler-builtins/libm/crates/util/src/main.rs2
-rw-r--r--library/compiler-builtins/libm/etc/function-definitions.json16
-rw-r--r--library/compiler-builtins/libm/etc/function-list.txt2
-rw-r--r--library/compiler-builtins/libm/src/math/generic/mod.rs2
-rw-r--r--library/compiler-builtins/libm/src/math/generic/round.rs82
-rw-r--r--library/compiler-builtins/libm/src/math/mod.rs4
-rw-r--r--library/compiler-builtins/libm/src/math/round.rs27
-rw-r--r--library/compiler-builtins/libm/src/math/roundf.rs29
-rw-r--r--library/compiler-builtins/libm/src/math/roundf128.rs5
-rw-r--r--library/compiler-builtins/libm/src/math/roundf16.rs5
15 files changed, 132 insertions, 57 deletions
diff --git a/library/compiler-builtins/libm/crates/libm-macros/src/shared.rs b/library/compiler-builtins/libm/crates/libm-macros/src/shared.rs
index 80bd3e90753..b233e34f182 100644
--- a/library/compiler-builtins/libm/crates/libm-macros/src/shared.rs
+++ b/library/compiler-builtins/libm/crates/libm-macros/src/shared.rs
@@ -9,7 +9,7 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
         FloatTy::F16,
         Signature { args: &[Ty::F16], returns: &[Ty::F16] },
         None,
-        &["ceilf16", "fabsf16", "floorf16", "rintf16", "sqrtf16", "truncf16"],
+        &["ceilf16", "fabsf16", "floorf16", "rintf16", "roundf16", "sqrtf16", "truncf16"],
     ),
     (
         // `fn(f32) -> f32`
@@ -40,7 +40,7 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
         FloatTy::F128,
         Signature { args: &[Ty::F128], returns: &[Ty::F128] },
         None,
-        &["ceilf128", "fabsf128", "floorf128", "rintf128", "sqrtf128", "truncf128"],
+        &["ceilf128", "fabsf128", "floorf128", "rintf128", "roundf128", "sqrtf128", "truncf128"],
     ),
     (
         // `(f16, f16) -> f16`
diff --git a/library/compiler-builtins/libm/crates/libm-test/benches/random.rs b/library/compiler-builtins/libm/crates/libm-test/benches/random.rs
index 4d050e817e2..d0ecd851e34 100644
--- a/library/compiler-builtins/libm/crates/libm-test/benches/random.rs
+++ b/library/compiler-builtins/libm/crates/libm-test/benches/random.rs
@@ -129,6 +129,8 @@ libm_macros::for_each_function! {
         | floorf16
         | rintf128
         | rintf16
+        | roundf128
+        | roundf16
         | sqrtf128
         | sqrtf16
         | truncf128
diff --git a/library/compiler-builtins/libm/crates/libm-test/src/mpfloat.rs b/library/compiler-builtins/libm/crates/libm-test/src/mpfloat.rs
index 4ac70c2eb5e..4422ab88d0d 100644
--- a/library/compiler-builtins/libm/crates/libm-test/src/mpfloat.rs
+++ b/library/compiler-builtins/libm/crates/libm-test/src/mpfloat.rs
@@ -175,6 +175,8 @@ libm_macros::for_each_function! {
         rintf16,
         round,
         roundf,
+        roundf128,
+        roundf16,
         scalbn,
         scalbnf,
         sincos,sincosf,
@@ -247,6 +249,7 @@ impl_no_round! {
     fabsf16 => abs_mut;
     floorf16 => floor_mut;
     rintf16 => round_even_mut; // FIXME: respect rounding mode
+    roundf16 => round_mut;
     truncf16 => trunc_mut;
 }
 
@@ -256,6 +259,7 @@ impl_no_round! {
     fabsf128 => abs_mut;
     floorf128 => floor_mut;
     rintf128 => round_even_mut; // FIXME: respect rounding mode
+    roundf128 => round_mut;
     truncf128 => trunc_mut;
 }
 
diff --git a/library/compiler-builtins/libm/crates/libm-test/src/precision.rs b/library/compiler-builtins/libm/crates/libm-test/src/precision.rs
index 800425f12ad..bed6158825a 100644
--- a/library/compiler-builtins/libm/crates/libm-test/src/precision.rs
+++ b/library/compiler-builtins/libm/crates/libm-test/src/precision.rs
@@ -13,9 +13,6 @@ use crate::{BaseName, CheckBasis, CheckCtx, Float, Identifier, Int, TestResult};
 pub struct SpecialCase;
 
 /// ULP allowed to differ from the results returned by a test basis.
-///
-/// Note that these results were obtained using 400M rounds of random inputs, which
-/// is not a value used by default.
 pub fn default_ulp(ctx: &CheckCtx) -> u32 {
     // ULP compared to the infinite (MPFR) result.
     let mut ulp = match ctx.base_name {
diff --git a/library/compiler-builtins/libm/crates/libm-test/tests/compare_built_musl.rs b/library/compiler-builtins/libm/crates/libm-test/tests/compare_built_musl.rs
index f009816c97f..0fc1b0df13d 100644
--- a/library/compiler-builtins/libm/crates/libm-test/tests/compare_built_musl.rs
+++ b/library/compiler-builtins/libm/crates/libm-test/tests/compare_built_musl.rs
@@ -91,6 +91,8 @@ libm_macros::for_each_function! {
         floorf16,
         rintf128,
         rintf16,
+        roundf128,
+        roundf16,
         sqrtf128,
         sqrtf16,
         truncf128,
diff --git a/library/compiler-builtins/libm/crates/util/src/main.rs b/library/compiler-builtins/libm/crates/util/src/main.rs
index 889823d2e4a..aaedda6d152 100644
--- a/library/compiler-builtins/libm/crates/util/src/main.rs
+++ b/library/compiler-builtins/libm/crates/util/src/main.rs
@@ -98,6 +98,8 @@ fn do_eval(basis: &str, op: &str, inputs: &[&str]) {
             | floorf16
             | rintf128
             | rintf16
+            | roundf128
+            | roundf16
             | sqrtf128
             | sqrtf16
             | truncf128
diff --git a/library/compiler-builtins/libm/etc/function-definitions.json b/library/compiler-builtins/libm/etc/function-definitions.json
index bbb2b40f14d..8c5903e93b9 100644
--- a/library/compiler-builtins/libm/etc/function-definitions.json
+++ b/library/compiler-builtins/libm/etc/function-definitions.json
@@ -685,16 +685,32 @@
     "round": {
         "sources": [
             "src/libm_helper.rs",
+            "src/math/generic/round.rs",
             "src/math/round.rs"
         ],
         "type": "f64"
     },
     "roundf": {
         "sources": [
+            "src/math/generic/round.rs",
             "src/math/roundf.rs"
         ],
         "type": "f32"
     },
+    "roundf128": {
+        "sources": [
+            "src/math/generic/round.rs",
+            "src/math/roundf128.rs"
+        ],
+        "type": "f128"
+    },
+    "roundf16": {
+        "sources": [
+            "src/math/generic/round.rs",
+            "src/math/roundf16.rs"
+        ],
+        "type": "f16"
+    },
     "scalbn": {
         "sources": [
             "src/libm_helper.rs",
diff --git a/library/compiler-builtins/libm/etc/function-list.txt b/library/compiler-builtins/libm/etc/function-list.txt
index 41bb4e06be8..0b6eed828b5 100644
--- a/library/compiler-builtins/libm/etc/function-list.txt
+++ b/library/compiler-builtins/libm/etc/function-list.txt
@@ -101,6 +101,8 @@ rintf128
 rintf16
 round
 roundf
+roundf128
+roundf16
 scalbn
 scalbnf
 sin
diff --git a/library/compiler-builtins/libm/src/math/generic/mod.rs b/library/compiler-builtins/libm/src/math/generic/mod.rs
index c7741cb4600..1f557719f42 100644
--- a/library/compiler-builtins/libm/src/math/generic/mod.rs
+++ b/library/compiler-builtins/libm/src/math/generic/mod.rs
@@ -4,6 +4,7 @@ mod fabs;
 mod fdim;
 mod floor;
 mod rint;
+mod round;
 mod scalbn;
 mod sqrt;
 mod trunc;
@@ -14,6 +15,7 @@ pub use fabs::fabs;
 pub use fdim::fdim;
 pub use floor::floor;
 pub use rint::rint;
+pub use round::round;
 pub use scalbn::scalbn;
 pub use sqrt::sqrt;
 pub use trunc::trunc;
diff --git a/library/compiler-builtins/libm/src/math/generic/round.rs b/library/compiler-builtins/libm/src/math/generic/round.rs
new file mode 100644
index 00000000000..8b51381880c
--- /dev/null
+++ b/library/compiler-builtins/libm/src/math/generic/round.rs
@@ -0,0 +1,82 @@
+use super::super::{Float, MinInt};
+use super::{copysign, trunc};
+
+pub fn round<F: Float>(x: F) -> F {
+    let f0p5 = F::from_parts(false, F::EXP_BIAS - 1, F::Int::ZERO); // 0.5
+    let f0p25 = F::from_parts(false, F::EXP_BIAS - 2, F::Int::ZERO); // 0.25
+
+    trunc(x + copysign(f0p5 - f0p25 * F::EPSILON, x))
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    #[cfg(f16_enabled)]
+    fn zeroes_f16() {
+        assert_biteq!(round(0.0_f16), 0.0_f16);
+        assert_biteq!(round(-0.0_f16), -0.0_f16);
+    }
+
+    #[test]
+    #[cfg(f16_enabled)]
+    fn sanity_check_f16() {
+        assert_eq!(round(-1.0_f16), -1.0);
+        assert_eq!(round(2.8_f16), 3.0);
+        assert_eq!(round(-0.5_f16), -1.0);
+        assert_eq!(round(0.5_f16), 1.0);
+        assert_eq!(round(-1.5_f16), -2.0);
+        assert_eq!(round(1.5_f16), 2.0);
+    }
+
+    #[test]
+    fn zeroes_f32() {
+        assert_biteq!(round(0.0_f32), 0.0_f32);
+        assert_biteq!(round(-0.0_f32), -0.0_f32);
+    }
+
+    #[test]
+    fn sanity_check_f32() {
+        assert_eq!(round(-1.0_f32), -1.0);
+        assert_eq!(round(2.8_f32), 3.0);
+        assert_eq!(round(-0.5_f32), -1.0);
+        assert_eq!(round(0.5_f32), 1.0);
+        assert_eq!(round(-1.5_f32), -2.0);
+        assert_eq!(round(1.5_f32), 2.0);
+    }
+
+    #[test]
+    fn zeroes_f64() {
+        assert_biteq!(round(0.0_f64), 0.0_f64);
+        assert_biteq!(round(-0.0_f64), -0.0_f64);
+    }
+
+    #[test]
+    fn sanity_check_f64() {
+        assert_eq!(round(-1.0_f64), -1.0);
+        assert_eq!(round(2.8_f64), 3.0);
+        assert_eq!(round(-0.5_f64), -1.0);
+        assert_eq!(round(0.5_f64), 1.0);
+        assert_eq!(round(-1.5_f64), -2.0);
+        assert_eq!(round(1.5_f64), 2.0);
+    }
+
+    #[test]
+    #[cfg(f128_enabled)]
+    fn zeroes_f128() {
+        assert_biteq!(round(0.0_f128), 0.0_f128);
+        assert_biteq!(round(-0.0_f128), -0.0_f128);
+    }
+
+    #[test]
+    #[cfg(f128_enabled)]
+    fn sanity_check_f128() {
+        assert_eq!(round(-1.0_f128), -1.0);
+        assert_eq!(round(2.8_f128), 3.0);
+        assert_eq!(round(-0.5_f128), -1.0);
+        assert_eq!(round(0.5_f128), 1.0);
+        assert_eq!(round(-1.5_f128), -2.0);
+        assert_eq!(round(1.5_f128), 2.0);
+    }
+}
diff --git a/library/compiler-builtins/libm/src/math/mod.rs b/library/compiler-builtins/libm/src/math/mod.rs
index 53d06974cee..8db17a02dfc 100644
--- a/library/compiler-builtins/libm/src/math/mod.rs
+++ b/library/compiler-builtins/libm/src/math/mod.rs
@@ -347,6 +347,7 @@ cfg_if! {
         mod fdimf16;
         mod floorf16;
         mod rintf16;
+        mod roundf16;
         mod sqrtf16;
         mod truncf16;
 
@@ -356,6 +357,7 @@ cfg_if! {
         pub use self::fdimf16::fdimf16;
         pub use self::floorf16::floorf16;
         pub use self::rintf16::rintf16;
+        pub use self::roundf16::roundf16;
         pub use self::sqrtf16::sqrtf16;
         pub use self::truncf16::truncf16;
     }
@@ -369,6 +371,7 @@ cfg_if! {
         mod fdimf128;
         mod floorf128;
         mod rintf128;
+        mod roundf128;
         mod sqrtf128;
         mod truncf128;
 
@@ -378,6 +381,7 @@ cfg_if! {
         pub use self::fdimf128::fdimf128;
         pub use self::floorf128::floorf128;
         pub use self::rintf128::rintf128;
+        pub use self::roundf128::roundf128;
         pub use self::sqrtf128::sqrtf128;
         pub use self::truncf128::truncf128;
     }
diff --git a/library/compiler-builtins/libm/src/math/round.rs b/library/compiler-builtins/libm/src/math/round.rs
index b81ebaa1dbe..36e0eb1f2ed 100644
--- a/library/compiler-builtins/libm/src/math/round.rs
+++ b/library/compiler-builtins/libm/src/math/round.rs
@@ -1,28 +1,5 @@
-use core::f64;
-
-use super::{copysign, trunc};
-
+/// Round `x` to the nearest integer, breaking ties away from zero.
 #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
 pub fn round(x: f64) -> f64 {
-    trunc(x + copysign(0.5 - 0.25 * f64::EPSILON, x))
-}
-
-#[cfg(test)]
-mod tests {
-    use super::round;
-
-    #[test]
-    fn negative_zero() {
-        assert_eq!(round(-0.0_f64).to_bits(), (-0.0_f64).to_bits());
-    }
-
-    #[test]
-    fn sanity_check() {
-        assert_eq!(round(-1.0), -1.0);
-        assert_eq!(round(2.8), 3.0);
-        assert_eq!(round(-0.5), -1.0);
-        assert_eq!(round(0.5), 1.0);
-        assert_eq!(round(-1.5), -2.0);
-        assert_eq!(round(1.5), 2.0);
-    }
+    super::generic::round(x)
 }
diff --git a/library/compiler-builtins/libm/src/math/roundf.rs b/library/compiler-builtins/libm/src/math/roundf.rs
index fb974bbfe73..b5d7c9d693e 100644
--- a/library/compiler-builtins/libm/src/math/roundf.rs
+++ b/library/compiler-builtins/libm/src/math/roundf.rs
@@ -1,30 +1,5 @@
-use core::f32;
-
-use super::{copysignf, truncf};
-
+/// Round `x` to the nearest integer, breaking ties away from zero.
 #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
 pub fn roundf(x: f32) -> f32 {
-    truncf(x + copysignf(0.5 - 0.25 * f32::EPSILON, x))
-}
-
-// PowerPC tests are failing on LLVM 13: https://github.com/rust-lang/rust/issues/88520
-#[cfg(not(target_arch = "powerpc64"))]
-#[cfg(test)]
-mod tests {
-    use super::roundf;
-
-    #[test]
-    fn negative_zero() {
-        assert_eq!(roundf(-0.0_f32).to_bits(), (-0.0_f32).to_bits());
-    }
-
-    #[test]
-    fn sanity_check() {
-        assert_eq!(roundf(-1.0), -1.0);
-        assert_eq!(roundf(2.8), 3.0);
-        assert_eq!(roundf(-0.5), -1.0);
-        assert_eq!(roundf(0.5), 1.0);
-        assert_eq!(roundf(-1.5), -2.0);
-        assert_eq!(roundf(1.5), 2.0);
-    }
+    super::generic::round(x)
 }
diff --git a/library/compiler-builtins/libm/src/math/roundf128.rs b/library/compiler-builtins/libm/src/math/roundf128.rs
new file mode 100644
index 00000000000..fc3164929fe
--- /dev/null
+++ b/library/compiler-builtins/libm/src/math/roundf128.rs
@@ -0,0 +1,5 @@
+/// Round `x` to the nearest integer, breaking ties away from zero.
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
+pub fn roundf128(x: f128) -> f128 {
+    super::generic::round(x)
+}
diff --git a/library/compiler-builtins/libm/src/math/roundf16.rs b/library/compiler-builtins/libm/src/math/roundf16.rs
new file mode 100644
index 00000000000..8b356eaabee
--- /dev/null
+++ b/library/compiler-builtins/libm/src/math/roundf16.rs
@@ -0,0 +1,5 @@
+/// Round `x` to the nearest integer, breaking ties away from zero.
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
+pub fn roundf16(x: f16) -> f16 {
+    super::generic::round(x)
+}