about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTrevor Gross <tmgross@umich.edu>2025-01-24 02:51:12 -0600
committerGitHub <noreply@github.com>2025-01-24 02:51:12 -0600
commit3524632b0b8d1955404d82f9a8a30a66bd187436 (patch)
tree97e016f2dc855db45bd362ac390508461f6bdbd8
parent9d38c93fb080ce30b2f57b017f9220f26f3b9d13 (diff)
parent71200bc3ce854c6c15e05c9588954b49a7aea095 (diff)
downloadrust-3524632b0b8d1955404d82f9a8a30a66bd187436.tar.gz
rust-3524632b0b8d1955404d82f9a8a30a66bd187436.zip
Merge pull request rust-lang/libm#470 from tgross35/f128-fmod
Add `fmodf128`
-rw-r--r--library/compiler-builtins/libm/crates/libm-macros/src/shared.rs2
-rw-r--r--library/compiler-builtins/libm/crates/libm-test/benches/icount.rs1
-rw-r--r--library/compiler-builtins/libm/crates/libm-test/benches/random.rs1
-rw-r--r--library/compiler-builtins/libm/crates/libm-test/src/lib.rs4
-rw-r--r--library/compiler-builtins/libm/crates/libm-test/src/mpfloat.rs47
-rw-r--r--library/compiler-builtins/libm/crates/libm-test/src/run_cfg.rs37
-rw-r--r--library/compiler-builtins/libm/crates/libm-test/tests/compare_built_musl.rs1
-rw-r--r--library/compiler-builtins/libm/crates/util/src/main.rs1
-rw-r--r--library/compiler-builtins/libm/etc/function-definitions.json7
-rw-r--r--library/compiler-builtins/libm/etc/function-list.txt1
-rw-r--r--library/compiler-builtins/libm/src/math/fmodf128.rs5
-rw-r--r--library/compiler-builtins/libm/src/math/mod.rs2
12 files changed, 68 insertions, 41 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 69fe45e03ce..b1f4f46cc3b 100644
--- a/library/compiler-builtins/libm/crates/libm-macros/src/shared.rs
+++ b/library/compiler-builtins/libm/crates/libm-macros/src/shared.rs
@@ -90,7 +90,7 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
         FloatTy::F128,
         Signature { args: &[Ty::F128, Ty::F128], returns: &[Ty::F128] },
         None,
-        &["copysignf128", "fdimf128", "fmaxf128", "fminf128"],
+        &["copysignf128", "fdimf128", "fmaxf128", "fminf128", "fmodf128"],
     ),
     (
         // `(f32, f32, f32) -> f32`
diff --git a/library/compiler-builtins/libm/crates/libm-test/benches/icount.rs b/library/compiler-builtins/libm/crates/libm-test/benches/icount.rs
index 97e78d8f1b1..46a659524a6 100644
--- a/library/compiler-builtins/libm/crates/libm-test/benches/icount.rs
+++ b/library/compiler-builtins/libm/crates/libm-test/benches/icount.rs
@@ -111,6 +111,7 @@ main!(
     icount_bench_fmin_group,
     icount_bench_fminf_group,
     icount_bench_fmod_group,
+    icount_bench_fmodf128_group,
     icount_bench_fmodf16_group,
     icount_bench_fmodf_group,
     icount_bench_frexp_group,
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 3e816e81a61..ca9e86c10bf 100644
--- a/library/compiler-builtins/libm/crates/libm-test/benches/random.rs
+++ b/library/compiler-builtins/libm/crates/libm-test/benches/random.rs
@@ -131,6 +131,7 @@ libm_macros::for_each_function! {
         | fmaxf16
         | fminf128
         | fminf16
+        | fmodf128
         | fmodf16
         | rintf128
         | rintf16
diff --git a/library/compiler-builtins/libm/crates/libm-test/src/lib.rs b/library/compiler-builtins/libm/crates/libm-test/src/lib.rs
index b90423c1bac..78b011b1f23 100644
--- a/library/compiler-builtins/libm/crates/libm-test/src/lib.rs
+++ b/library/compiler-builtins/libm/crates/libm-test/src/lib.rs
@@ -28,7 +28,7 @@ pub use op::{
     Ty,
 };
 pub use precision::{MaybeOverride, SpecialCase, default_ulp};
-use run_cfg::EXTENSIVE_MAX_ITERATIONS;
+use run_cfg::extensive_max_iterations;
 pub use run_cfg::{CheckBasis, CheckCtx, EXTENSIVE_ENV, GeneratorKind, skip_extensive_test};
 pub use test_traits::{CheckOutput, Hex, TupleCall};
 
@@ -89,7 +89,7 @@ pub fn test_log(s: &str) {
         writeln!(f, "cargo features: {}", env!("CFG_CARGO_FEATURES")).unwrap();
         writeln!(f, "opt level: {}", env!("CFG_OPT_LEVEL")).unwrap();
         writeln!(f, "target features: {}", env!("CFG_TARGET_FEATURES")).unwrap();
-        writeln!(f, "extensive iterations {}", *EXTENSIVE_MAX_ITERATIONS).unwrap();
+        writeln!(f, "extensive iterations {}", extensive_max_iterations()).unwrap();
 
         Some(f)
     });
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 56234b14a52..98b80505f26 100644
--- a/library/compiler-builtins/libm/crates/libm-test/src/mpfloat.rs
+++ b/library/compiler-builtins/libm/crates/libm-test/src/mpfloat.rs
@@ -152,6 +152,7 @@ libm_macros::for_each_function! {
         floorf16,
         fmod,
         fmodf,
+        fmodf128,
         fmodf16,
         frexp,
         frexpf,
@@ -301,21 +302,6 @@ macro_rules! impl_op_for_ty {
                 }
             }
 
-            impl MpOp for crate::op::[<fmod $suffix>]::Routine {
-                type MpTy = (MpFloat, MpFloat);
-
-                fn new_mp() -> Self::MpTy {
-                    (new_mpfloat::<Self::FTy>(), new_mpfloat::<Self::FTy>())
-                }
-
-                fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
-                    this.0.assign(input.0);
-                    this.1.assign(input.1);
-                    let ord = this.0.rem_assign_round(&this.1, Nearest);
-                    prep_retval::<Self::RustRet>(&mut this.0, ord)
-                }
-            }
-
             impl MpOp for crate::op::[<frexp $suffix>]::Routine {
                 type MpTy = MpFloat;
 
@@ -481,6 +467,21 @@ macro_rules! impl_op_for_ty_all {
                     prep_retval::<Self::RustRet>(&mut this.0, Ordering::Equal)
                 }
             }
+
+            impl MpOp for crate::op::[<fmod $suffix>]::Routine {
+                type MpTy = (MpFloat, MpFloat);
+
+                fn new_mp() -> Self::MpTy {
+                    (new_mpfloat::<Self::FTy>(), new_mpfloat::<Self::FTy>())
+                }
+
+                fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
+                    this.0.assign(input.0);
+                    this.1.assign(input.1);
+                    let ord = this.0.rem_assign_round(&this.1, Nearest);
+                    prep_retval::<Self::RustRet>(&mut this.0, ord)
+                }
+            }
         }
     };
 }
@@ -526,22 +527,6 @@ impl MpOp for crate::op::lgammaf_r::Routine {
     }
 }
 
-// No fmodf128 yet
-impl MpOp for crate::op::fmodf16::Routine {
-    type MpTy = (MpFloat, MpFloat);
-
-    fn new_mp() -> Self::MpTy {
-        (new_mpfloat::<Self::FTy>(), new_mpfloat::<Self::FTy>())
-    }
-
-    fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
-        this.0.assign(input.0);
-        this.1.assign(input.1);
-        let ord = this.0.rem_assign_round(&this.1, Nearest);
-        prep_retval::<Self::RustRet>(&mut this.0, ord)
-    }
-}
-
 /* stub implementations so we don't need to special case them */
 
 impl MpOp for crate::op::nextafter::Routine {
diff --git a/library/compiler-builtins/libm/crates/libm-test/src/run_cfg.rs b/library/compiler-builtins/libm/crates/libm-test/src/run_cfg.rs
index 3e91101f6ca..783142e3783 100644
--- a/library/compiler-builtins/libm/crates/libm-test/src/run_cfg.rs
+++ b/library/compiler-builtins/libm/crates/libm-test/src/run_cfg.rs
@@ -13,18 +13,30 @@ pub const EXTENSIVE_ENV: &str = "LIBM_EXTENSIVE_TESTS";
 /// Specify the number of iterations via this environment variable, rather than using the default.
 pub const EXTENSIVE_ITER_ENV: &str = "LIBM_EXTENSIVE_ITERATIONS";
 
+/// The override value, if set by the above environment.
+static EXTENSIVE_ITER_OVERRIDE: LazyLock<Option<u64>> = LazyLock::new(|| {
+    env::var(EXTENSIVE_ITER_ENV).map(|v| v.parse().expect("failed to parse iteration count")).ok()
+});
+
+/// Specific tests that need to have a reduced amount of iterations to complete in a reasonable
+/// amount of time.
+///
+/// Contains the itentifier+generator combo to match on, plus the factor to reduce by.
+const EXTEMELY_SLOW_TESTS: &[(Identifier, GeneratorKind, u64)] = &[
+    (Identifier::Fmodf128, GeneratorKind::QuickSpaced, 40),
+    (Identifier::Fmodf128, GeneratorKind::Extensive, 40),
+];
+
 /// Maximum number of iterations to run for a single routine.
 ///
 /// The default value of one greater than `u32::MAX` allows testing single-argument `f32` routines
 /// and single- or double-argument `f16` routines exhaustively. `f64` and `f128` can't feasibly
 /// be tested exhaustively; however, [`EXTENSIVE_ITER_ENV`] can be set to run tests for multiple
 /// hours.
-pub static EXTENSIVE_MAX_ITERATIONS: LazyLock<u64> = LazyLock::new(|| {
-    let default = 1 << 32;
-    env::var(EXTENSIVE_ITER_ENV)
-        .map(|v| v.parse().expect("failed to parse iteration count"))
-        .unwrap_or(default)
-});
+pub fn extensive_max_iterations() -> u64 {
+    let default = 1 << 32; // default value
+    EXTENSIVE_ITER_OVERRIDE.unwrap_or(default)
+}
 
 /// Context passed to [`CheckOutput`].
 #[derive(Clone, Debug, PartialEq, Eq)]
@@ -206,12 +218,23 @@ pub fn iteration_count(ctx: &CheckCtx, argnum: usize) -> u64 {
     let mut total_iterations = match ctx.gen_kind {
         GeneratorKind::QuickSpaced => domain_iter_count,
         GeneratorKind::Random => random_iter_count,
-        GeneratorKind::Extensive => *EXTENSIVE_MAX_ITERATIONS,
+        GeneratorKind::Extensive => extensive_max_iterations(),
         GeneratorKind::EdgeCases => {
             unimplemented!("edge case tests shoudn't need `iteration_count`")
         }
     };
 
+    // Some tests are significantly slower than others and need to be further reduced.
+    if let Some((_id, _gen, scale)) = EXTEMELY_SLOW_TESTS
+        .iter()
+        .find(|(id, gen, _scale)| *id == ctx.fn_ident && *gen == ctx.gen_kind)
+    {
+        // However, do not override if the extensive iteration count has been manually set.
+        if !(ctx.gen_kind == GeneratorKind::Extensive && EXTENSIVE_ITER_OVERRIDE.is_some()) {
+            total_iterations /= scale;
+        }
+    }
+
     // FMA has a huge domain but is reasonably fast to run, so increase iterations.
     if ctx.base_name == BaseName::Fma {
         total_iterations *= 4;
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 46474c04688..5466edf4f4c 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
@@ -93,6 +93,7 @@ libm_macros::for_each_function! {
         fmaxf16,
         fminf128,
         fminf16,
+        fmodf128,
         fmodf16,
         rintf128,
         rintf16,
diff --git a/library/compiler-builtins/libm/crates/util/src/main.rs b/library/compiler-builtins/libm/crates/util/src/main.rs
index 999b03af9e3..f4ee8fd2e38 100644
--- a/library/compiler-builtins/libm/crates/util/src/main.rs
+++ b/library/compiler-builtins/libm/crates/util/src/main.rs
@@ -100,6 +100,7 @@ fn do_eval(basis: &str, op: &str, inputs: &[&str]) {
             | fmaxf16
             | fminf128
             | fminf16
+            | fmodf128
             | fmodf16
             | rintf128
             | rintf16
diff --git a/library/compiler-builtins/libm/etc/function-definitions.json b/library/compiler-builtins/libm/etc/function-definitions.json
index 966060f77c4..574ffea2e50 100644
--- a/library/compiler-builtins/libm/etc/function-definitions.json
+++ b/library/compiler-builtins/libm/etc/function-definitions.json
@@ -449,6 +449,13 @@
         ],
         "type": "f32"
     },
+    "fmodf128": {
+        "sources": [
+            "src/math/fmodf128.rs",
+            "src/math/generic/fmod.rs"
+        ],
+        "type": "f128"
+    },
     "fmodf16": {
         "sources": [
             "src/math/fmodf16.rs",
diff --git a/library/compiler-builtins/libm/etc/function-list.txt b/library/compiler-builtins/libm/etc/function-list.txt
index ff4de0cb5d4..d82838b3233 100644
--- a/library/compiler-builtins/libm/etc/function-list.txt
+++ b/library/compiler-builtins/libm/etc/function-list.txt
@@ -63,6 +63,7 @@ fminf128
 fminf16
 fmod
 fmodf
+fmodf128
 fmodf16
 frexp
 frexpf
diff --git a/library/compiler-builtins/libm/src/math/fmodf128.rs b/library/compiler-builtins/libm/src/math/fmodf128.rs
new file mode 100644
index 00000000000..ff0e0493e26
--- /dev/null
+++ b/library/compiler-builtins/libm/src/math/fmodf128.rs
@@ -0,0 +1,5 @@
+/// Calculate the remainder of `x / y`, the precise result of `x - trunc(x / y) * y`.
+#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
+pub fn fmodf128(x: f128, y: f128) -> f128 {
+    super::generic::fmod(x, y)
+}
diff --git a/library/compiler-builtins/libm/src/math/mod.rs b/library/compiler-builtins/libm/src/math/mod.rs
index aab551bedbd..969c1bfd942 100644
--- a/library/compiler-builtins/libm/src/math/mod.rs
+++ b/library/compiler-builtins/libm/src/math/mod.rs
@@ -378,6 +378,7 @@ cfg_if! {
         mod floorf128;
         mod fmaxf128;
         mod fminf128;
+        mod fmodf128;
         mod rintf128;
         mod roundf128;
         mod sqrtf128;
@@ -390,6 +391,7 @@ cfg_if! {
         pub use self::floorf128::floorf128;
         pub use self::fmaxf128::fmaxf128;
         pub use self::fminf128::fminf128;
+        pub use self::fmodf128::fmodf128;
         pub use self::rintf128::rintf128;
         pub use self::roundf128::roundf128;
         pub use self::sqrtf128::sqrtf128;