+rust-libm (0.2.1-5) UNRELEASED-FIXME-AUTOGENERATED-DEBCARGO; urgency=medium
+
+ * Team upload.
+ * Package libm 0.2.1 from crates.io using debcargo 2.5.0
+ * Apply an upstream fix that fixes a build error when manually running
+ cargo test (this doesn't seem to apply when running under cargo_auto_test,
+ it appears cargo_auto_test overrides the maximum lint level somehow).
+ * Update x87 patches to more closely match what was accepted upstream
+ and to fix most errors in release mode as well as debug mode.
+
+ -- Peter Michael Green <plugwash@debian.org> Tue, 04 Jan 2022 22:59:50 +0000
+
rust-libm (0.2.1-4) unstable; urgency=medium
* Team upload.
Files: debian/*
Copyright:
- 2020-2021 Debian Rust Maintainers <pkg-rust-maintainers@alioth-lists.debian.net>
- 2020-2021 Andrej Shadura <andrewsh@debian.org>
+ 2020-2022 Debian Rust Maintainers <pkg-rust-maintainers@alioth-lists.debian.net>
+ 2020-2022 Andrej Shadura <andrewsh@debian.org>
License: MIT or Apache-2.0
License: Apache-2.0
+++ /dev/null
-Index: rust-libm-0.2.1/src/math/rem_pio2.rs
-===================================================================
---- rust-libm-0.2.1.orig/src/math/rem_pio2.rs
-+++ rust-libm-0.2.1/src/math/rem_pio2.rs
-@@ -50,7 +50,9 @@ pub(crate) fn rem_pio2(x: f64) -> (i32,
-
- fn medium(x: f64, ix: u32) -> (i32, f64, f64) {
- /* rint(x/(pi/2)), Assume round-to-nearest. */
-- let f_n = x as f64 * INV_PIO2 + TO_INT - TO_INT;
-+ //use to_bits and from_bits to force rounding to the storage format,
-+ //otherwise this doesn't work on x87
-+ let f_n = f64::from_bits((x as f64 * INV_PIO2 + TO_INT).to_bits()) - TO_INT;
- let n = f_n as i32;
- let mut r = x - f_n * PIO2_1;
- let mut w = f_n * PIO2_1T; /* 1st round, good to 85 bits */
+++ /dev/null
-From 1b41fb03b51740a4323e5dbb09390b30a8f926f8 Mon Sep 17 00:00:00 2001
-From: Peter Michael Green <plugwash@debian.org>
-Date: Sat, 2 Jan 2021 04:11:40 +0000
-Subject: [PATCH] Fix testcases on x87
-
----
- src/lib.rs | 1 +
- src/math/ceil.rs | 17 +++++++++++++++++
- src/math/floor.rs | 17 +++++++++++++++++
- src/math/j1f.rs | 6 +++++-
- src/math/rem_pio2f.rs | 2 +-
- src/math/round.rs | 2 +-
- src/math/roundf.rs | 2 +-
- src/math/sincosf.rs | 5 ++++-
- 8 files changed, 47 insertions(+), 5 deletions(-)
-
---- a/src/lib.rs
-+++ b/src/lib.rs
-@@ -1,5 +1,6 @@
- //! libm in pure Rust
- #![deny(warnings)]
-+#![allow(unreachable_code)]
- #![no_std]
- #![cfg_attr(
- all(target_arch = "wasm32", feature = "unstable"),
---- a/src/math/ceil.rs
-+++ b/src/math/ceil.rs
-@@ -1,4 +1,5 @@
- use core::f64;
-+use super::fabs;
-
- const TOINT: f64 = 1. / f64::EPSILON;
-
-@@ -15,6 +16,22 @@ pub fn ceil(x: f64) -> f64 {
- return unsafe { ::core::intrinsics::ceilf64(x) }
- }
- }
-+ #[cfg(target_arch = "x86")] {
-+ //use an alternative implementation on x86, because the
-+ //main implementation fails with the x87 FPU used by
-+ //debian i386, probablly due to excess precision issues.
-+ //basic implementation taken from https://github.com/rust-lang/libm/issues/219
-+ if fabs(x).to_bits() < 4503599627370496.0_f64.to_bits() {
-+ let truncated = x as i64 as f64;
-+ if truncated < x {
-+ return truncated + 1.0;
-+ } else {
-+ return truncated
-+ }
-+ } else {
-+ return x;
-+ }
-+ }
- let u: u64 = x.to_bits();
- let e: i64 = (u >> 52 & 0x7ff) as i64;
- let y: f64;
---- a/src/math/floor.rs
-+++ b/src/math/floor.rs
-@@ -1,4 +1,5 @@
- use core::f64;
-+use super::fabs;
-
- const TOINT: f64 = 1. / f64::EPSILON;
-
-@@ -15,6 +16,22 @@ pub fn floor(x: f64) -> f64 {
- return unsafe { ::core::intrinsics::floorf64(x) }
- }
- }
-+ #[cfg(target_arch = "x86")] {
-+ //use an alternative implementation on x86, because the
-+ //main implementation fails with the x87 FPU used by
-+ //debian i386, probablly due to excess precision issues.
-+ //basic implementation taken from https://github.com/rust-lang/libm/issues/219
-+ if fabs(x).to_bits() < 4503599627370496.0_f64.to_bits() {
-+ let truncated = x as i64 as f64;
-+ if truncated > x {
-+ return truncated - 1.0;
-+ } else {
-+ return truncated
-+ }
-+ } else {
-+ return x;
-+ }
-+ }
- let ui = x.to_bits();
- let e = ((ui >> 52) & 0x7ff) as i32;
-
---- a/src/math/j1f.rs
-+++ b/src/math/j1f.rs
-@@ -367,6 +367,10 @@ mod tests {
- }
- #[test]
- fn test_y1f_2002() {
-- assert_eq!(y1f(2.0000002_f32), -0.10703229_f32);
-+ //allow slightly different result on x87
-+ let res = y1f(2.0000002_f32);
-+ if res != -0.10703231_f32 {
-+ assert_eq!(res, -0.10703229_f32);
-+ }
- }
- }
---- a/src/math/rem_pio2f.rs
-+++ b/src/math/rem_pio2f.rs
-@@ -43,7 +43,7 @@ pub(crate) fn rem_pio2f(x: f32) -> (i32,
- if ix < 0x4dc90fdb {
- /* |x| ~< 2^28*(pi/2), medium size */
- /* Use a specialized rint() to get fn. Assume round-to-nearest. */
-- let f_n = x64 * INV_PIO2 + TOINT - TOINT;
-+ let f_n = f64::from_bits((x64 * INV_PIO2 + TOINT).to_bits()) - TOINT;
- return (f_n as i32, x64 - f_n * PIO2_1 - f_n * PIO2_1T);
- }
- if ix >= 0x7f800000 {
---- a/src/math/round.rs
-+++ b/src/math/round.rs
-@@ -19,7 +19,7 @@ pub fn round(mut x: f64) -> f64 {
- if i >> 63 != 0 {
- x = -x;
- }
-- y = x + TOINT - TOINT - x;
-+ y = f64::from_bits((x + TOINT).to_bits()) - TOINT - x;
- if y > 0.5 {
- y = y + x - 1.0;
- } else if y <= -0.5 {
---- a/src/math/roundf.rs
-+++ b/src/math/roundf.rs
-@@ -18,7 +18,7 @@ pub fn roundf(mut x: f32) -> f32 {
- if i >> 31 != 0 {
- x = -x;
- }
-- y = x + TOINT - TOINT - x;
-+ y = f32::from_bits((x + TOINT).to_bits()) - TOINT - x;
- if y > 0.5f32 {
- y = y + x - 1.0;
- } else if y <= -0.5f32 {
---- a/src/math/sincosf.rs
-+++ b/src/math/sincosf.rs
-@@ -145,7 +145,10 @@ mod tests {
- let (s_minus, c_minus) = sincosf(theta - 2. * PI);
-
- const TOLERANCE: f32 = 1e-6;
-- assert!((s - s_plus).abs() < TOLERANCE);
-+ //hack so it's possible to see how far out of tolerance the results are
-+ if (s - s_plus).abs() >= TOLERANCE {
-+ assert_eq!((s - s_plus).abs(),TOLERANCE);
-+ }
- assert!((s - s_minus).abs() < TOLERANCE);
- assert!((c - c_plus).abs() < TOLERANCE);
- assert!((c - c_minus).abs() < TOLERANCE);
--- /dev/null
+commit c18c704856ffa8b3349401300e66796d4cc8d4f5
+Author: Jethro Beekman <jethro@fortanix.com>
+Date: Thu Jun 24 15:58:36 2021 +0200
+
+ Fix build failure with latest nightly
+
+diff --git a/src/math/pow.rs b/src/math/pow.rs
+index c7fd0df..f79680a 100644
+--- a/src/math/pow.rs
++++ b/src/math/pow.rs
+@@ -604,7 +604,7 @@ mod tests {
+
+ // Factoring -1 out:
+ // (negative anything ^ integer should be (-1 ^ integer) * (positive anything ^ integer))
+- &[POS_ZERO, NEG_ZERO, POS_ONE, NEG_ONE, POS_EVENS, NEG_EVENS]
++ (&[POS_ZERO, NEG_ZERO, POS_ONE, NEG_ONE, POS_EVENS, NEG_EVENS])
+ .iter()
+ .for_each(|int_set| {
+ int_set.iter().for_each(|int| {
+@@ -616,7 +616,7 @@ mod tests {
+
+ // Negative base (imaginary results):
+ // (-anything except 0 and Infinity ^ non-integer should be NAN)
+- &NEG[1..(NEG.len() - 1)].iter().for_each(|set| {
++ (&NEG[1..(NEG.len() - 1)]).iter().for_each(|set| {
+ set.iter().for_each(|val| {
+ test_sets(&ALL[3..7], &|v: f64| pow(*val, v), &|_| NAN);
+ })
features.patch
-fix-tests.patch
-fix-rem-pio2.patch
+fix-unused-result-error.patch
+x87-01-force-test-eval-runtime.patch
+x87-02-fix-testcases.patch
+x87-03-use-force-eval.patch
+x87-04-fix-rem-pio2.patch
+x87-05-round-to-storage-format-in.tests.patch
+x87-06-only-allow-x87-result-on-x87.patch
+x87-07-allow-force-eval-to-produce-result.patch
+x87-08-fix-round-and-roundf.patch
--- /dev/null
+commit 5672d6722919a6bdd9fbb386eec667fb091f4cbc
+Author: Peter Michael Green <plugwash@debian.org>
+Date: Wed Dec 22 00:56:18 2021 +0000
+
+ force test_near_pi in rem_pio2.rs to be evaluated at runtime not compiletime.
+
+diff --git a/src/math/rem_pio2.rs b/src/math/rem_pio2.rs
+index 46f7c38..f58fa35 100644
+--- a/src/math/rem_pio2.rs
++++ b/src/math/rem_pio2.rs
+@@ -190,20 +190,28 @@ mod tests {
+
+ #[test]
+ fn test_near_pi() {
++ let arg = 3.141592025756836;
++ force_eval!(arg);
+ assert_eq!(
+- rem_pio2(3.141592025756836),
++ rem_pio2(arg),
+ (2, -6.278329573009626e-7, -2.1125998133974653e-23)
+ );
++ let arg = 3.141592033207416;
++ force_eval!(arg);
+ assert_eq!(
+- rem_pio2(3.141592033207416),
++ rem_pio2(arg),
+ (2, -6.20382377148128e-7, -2.1125998133974653e-23)
+ );
++ let arg = 3.141592144966125;
++ force_eval!(arg);
+ assert_eq!(
+- rem_pio2(3.141592144966125),
++ rem_pio2(arg),
+ (2, -5.086236681942706e-7, -2.1125998133974653e-23)
+ );
++ let arg = 3.141592979431152;
++ force_eval!(arg);
+ assert_eq!(
+- rem_pio2(3.141592979431152),
++ rem_pio2(arg),
+ (2, 3.2584135866119817e-7, -2.1125998133974653e-23)
+ );
+ }
--- /dev/null
+commit 8b0db9f5baacf87494547f23bb656c1903825baf
+Author: Peter Michael Green <plugwash@debian.org>
+Date: Tue Jan 5 17:32:30 2021 +0000
+
+ Fix testcases on x87
+
+diff --git a/src/math/ceil.rs b/src/math/ceil.rs
+index eda28b9..22d8929 100644
+--- a/src/math/ceil.rs
++++ b/src/math/ceil.rs
+@@ -1,3 +1,4 @@
++#![allow(unreachable_code)]
+ use core::f64;
+
+ const TOINT: f64 = 1. / f64::EPSILON;
+@@ -15,6 +16,24 @@ pub fn ceil(x: f64) -> f64 {
+ return unsafe { ::core::intrinsics::ceilf64(x) }
+ }
+ }
++ #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
++ {
++ //use an alternative implementation on x86, because the
++ //main implementation fails with the x87 FPU used by
++ //debian i386, probablly due to excess precision issues.
++ //basic implementation taken from https://github.com/rust-lang/libm/issues/219
++ use super::fabs;
++ if fabs(x).to_bits() < 4503599627370496.0_f64.to_bits() {
++ let truncated = x as i64 as f64;
++ if truncated < x {
++ return truncated + 1.0;
++ } else {
++ return truncated;
++ }
++ } else {
++ return x;
++ }
++ }
+ let u: u64 = x.to_bits();
+ let e: i64 = (u >> 52 & 0x7ff) as i64;
+ let y: f64;
+diff --git a/src/math/floor.rs b/src/math/floor.rs
+index b2b7605..d09f9a1 100644
+--- a/src/math/floor.rs
++++ b/src/math/floor.rs
+@@ -1,3 +1,4 @@
++#![allow(unreachable_code)]
+ use core::f64;
+
+ const TOINT: f64 = 1. / f64::EPSILON;
+@@ -15,6 +16,24 @@ pub fn floor(x: f64) -> f64 {
+ return unsafe { ::core::intrinsics::floorf64(x) }
+ }
+ }
++ #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
++ {
++ //use an alternative implementation on x86, because the
++ //main implementation fails with the x87 FPU used by
++ //debian i386, probablly due to excess precision issues.
++ //basic implementation taken from https://github.com/rust-lang/libm/issues/219
++ use super::fabs;
++ if fabs(x).to_bits() < 4503599627370496.0_f64.to_bits() {
++ let truncated = x as i64 as f64;
++ if truncated > x {
++ return truncated - 1.0;
++ } else {
++ return truncated;
++ }
++ } else {
++ return x;
++ }
++ }
+ let ui = x.to_bits();
+ let e = ((ui >> 52) & 0x7ff) as i32;
+
+diff --git a/src/math/j1f.rs b/src/math/j1f.rs
+index 3369490..225b719 100644
+--- a/src/math/j1f.rs
++++ b/src/math/j1f.rs
+@@ -369,6 +369,10 @@ mod tests {
+ }
+ #[test]
+ fn test_y1f_2002() {
+- assert_eq!(y1f(2.0000002_f32), -0.10703229_f32);
++ //allow slightly different result on x87
++ let res = y1f(2.0000002_f32);
++ if res != -0.10703231_f32 {
++ assert_eq!(res, -0.10703229_f32);
++ }
+ }
+ }
+diff --git a/src/math/rem_pio2f.rs b/src/math/rem_pio2f.rs
+index 5d392ba..4d4499b 100644
+--- a/src/math/rem_pio2f.rs
++++ b/src/math/rem_pio2f.rs
+@@ -43,7 +43,9 @@ pub(crate) fn rem_pio2f(x: f32) -> (i32, f64) {
+ if ix < 0x4dc90fdb {
+ /* |x| ~< 2^28*(pi/2), medium size */
+ /* Use a specialized rint() to get fn. Assume round-to-nearest. */
+- let f_n = x64 * INV_PIO2 + TOINT - TOINT;
++ // use to_bits and from_bits to force rounding to storage format on
++ // x87.
++ let f_n = f64::from_bits((x64 * INV_PIO2 + TOINT).to_bits()) - TOINT;
+ return (f_n as i32, x64 - f_n * PIO2_1 - f_n * PIO2_1T);
+ }
+ if ix >= 0x7f800000 {
+diff --git a/src/math/sincosf.rs b/src/math/sincosf.rs
+index 83c9f40..5304e8c 100644
+--- a/src/math/sincosf.rs
++++ b/src/math/sincosf.rs
+@@ -147,10 +147,38 @@ mod tests {
+ let (s_minus, c_minus) = sincosf(theta - 2. * PI);
+
+ const TOLERANCE: f32 = 1e-6;
+- assert!((s - s_plus).abs() < TOLERANCE);
+- assert!((s - s_minus).abs() < TOLERANCE);
+- assert!((c - c_plus).abs() < TOLERANCE);
+- assert!((c - c_minus).abs() < TOLERANCE);
++ assert!(
++ (s - s_plus).abs() < TOLERANCE,
++ "|{} - {}| = {} >= {}",
++ s,
++ s_plus,
++ (s - s_plus).abs(),
++ TOLERANCE
++ );
++ assert!(
++ (s - s_minus).abs() < TOLERANCE,
++ "|{} - {}| = {} >= {}",
++ s,
++ s_minus,
++ (s - s_minus).abs(),
++ TOLERANCE
++ );
++ assert!(
++ (c - c_plus).abs() < TOLERANCE,
++ "|{} - {}| = {} >= {}",
++ c,
++ c_plus,
++ (c - c_plus).abs(),
++ TOLERANCE
++ );
++ assert!(
++ (c - c_minus).abs() < TOLERANCE,
++ "|{} - {}| = {} >= {}",
++ c,
++ c_minus,
++ (c - c_minus).abs(),
++ TOLERANCE
++ );
+ }
+ }
+ }
--- /dev/null
+commit 16ce35bb191ed075dae3668257025feed2cf169f
+Author: Peter Michael Green <plugwash@debian.org>
+Date: Tue Dec 21 22:41:29 2021 +0000
+
+ Use force_eval instead of to_bits/from_bits combination,
+
+ Using to_bits/from_bits to force conversion to storage format
+ apparently doesn't work in release mode. Also add an architecture
+ conditional to avoid pessimising other architectures.
+
+diff --git a/src/math/rem_pio2f.rs b/src/math/rem_pio2f.rs
+index 4d4499b..3ce8f9a 100644
+--- a/src/math/rem_pio2f.rs
++++ b/src/math/rem_pio2f.rs
+@@ -43,9 +43,11 @@ pub(crate) fn rem_pio2f(x: f32) -> (i32, f64) {
+ if ix < 0x4dc90fdb {
+ /* |x| ~< 2^28*(pi/2), medium size */
+ /* Use a specialized rint() to get fn. Assume round-to-nearest. */
+- // use to_bits and from_bits to force rounding to storage format on
+- // x87.
+- let f_n = f64::from_bits((x64 * INV_PIO2 + TOINT).to_bits()) - TOINT;
++ let tmp = x64 * INV_PIO2 + TOINT;
++ // force rounding of tmp to it's storage format on x87 to avoid
++ // excess precision issues.
++ #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]force_eval!(tmp);
++ let f_n = tmp - TOINT;
+ return (f_n as i32, x64 - f_n * PIO2_1 - f_n * PIO2_1T);
+ }
+ if ix >= 0x7f800000 {
--- /dev/null
+commit fa70d9bda797b5a78b1fb9a6ed7b372935f14e6e
+Author: Peter Michael Green <plugwash@debian.org>
+Date: Tue Dec 21 23:53:06 2021 +0000
+
+ Add forced rounding to storage format for x87 to rem_pio2.rs as well.
+
+diff --git a/src/math/rem_pio2.rs b/src/math/rem_pio2.rs
+index f58fa35..4ac9415 100644
+--- a/src/math/rem_pio2.rs
++++ b/src/math/rem_pio2.rs
+@@ -50,7 +50,11 @@ pub(crate) fn rem_pio2(x: f64) -> (i32, f64, f64) {
+
+ fn medium(x: f64, ix: u32) -> (i32, f64, f64) {
+ /* rint(x/(pi/2)), Assume round-to-nearest. */
+- let f_n = x as f64 * INV_PIO2 + TO_INT - TO_INT;
++ let tmp = x as f64 * INV_PIO2 + TO_INT;
++ // force rounding of tmp to it's storage format on x87 to avoid
++ // excess precision issues.
++ #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]force_eval!(tmp);
++ let f_n = tmp - TO_INT;
+ let n = f_n as i32;
+ let mut r = x - f_n * PIO2_1;
+ let mut w = f_n * PIO2_1T; /* 1st round, good to 85 bits */
+diff --git a/src/math/sincos.rs b/src/math/sincos.rs
+index d49f65c..bfc4561 100644
+--- a/src/math/sincos.rs
++++ b/src/math/sincos.rs
+@@ -57,3 +57,77 @@ pub fn sincos(x: f64) -> (f64, f64) {
+ _ => (0.0, 1.0),
+ }
+ }
++
++// These tests are based on those from sincosf.rs
++#[cfg(test)]
++mod tests {
++ use super::sincos;
++
++ const TOLERANCE: f64 = 1e-6;
++
++ #[test]
++ fn with_pi() {
++ let (s, c) = sincos(core::f64::consts::PI);
++ assert!(
++ (s - 0.0).abs() < TOLERANCE,
++ "|{} - {}| = {} >= {}",
++ s,
++ 0.0,
++ (s - 0.0).abs(),
++ TOLERANCE
++ );
++ assert!(
++ (c + 1.0).abs() < TOLERANCE,
++ "|{} + {}| = {} >= {}",
++ c,
++ 1.0,
++ (s + 1.0).abs(),
++ TOLERANCE
++ );
++ }
++
++ #[test]
++ fn rotational_symmetry() {
++ use core::f64::consts::PI;
++ const N: usize = 24;
++ for n in 0..N {
++ let theta = 2. * PI * (n as f64) / (N as f64);
++ let (s, c) = sincos(theta);
++ let (s_plus, c_plus) = sincos(theta + 2. * PI);
++ let (s_minus, c_minus) = sincos(theta - 2. * PI);
++
++ assert!(
++ (s - s_plus).abs() < TOLERANCE,
++ "|{} - {}| = {} >= {}",
++ s,
++ s_plus,
++ (s - s_plus).abs(),
++ TOLERANCE
++ );
++ assert!(
++ (s - s_minus).abs() < TOLERANCE,
++ "|{} - {}| = {} >= {}",
++ s,
++ s_minus,
++ (s - s_minus).abs(),
++ TOLERANCE
++ );
++ assert!(
++ (c - c_plus).abs() < TOLERANCE,
++ "|{} - {}| = {} >= {}",
++ c,
++ c_plus,
++ (c - c_plus).abs(),
++ TOLERANCE
++ );
++ assert!(
++ (c - c_minus).abs() < TOLERANCE,
++ "|{} - {}| = {} >= {}",
++ c,
++ c_minus,
++ (c - c_minus).abs(),
++ TOLERANCE
++ );
++ }
++ }
++}
--- /dev/null
+This patch is based on the commit below which has been submitted
+as part of https://github.com/rust-lang/libm/pull/249
+adapted for use in the Debian package.
+
+commit db80cfb90663284dd351f85284cb2a1b295d4043
+Author: Peter Michael Green <plugwash@debian.org>
+Date: Wed Dec 22 00:21:25 2021 +0000
+
+ round to storage format in some tests before comparison to prevent spurious errors on x87.
+
+Index: rust-libm-0.2.1/src/math/fma.rs
+===================================================================
+--- rust-libm-0.2.1.orig/src/math/fma.rs
++++ rust-libm-0.2.1/src/math/fma.rs
+@@ -218,6 +218,9 @@ mod tests {
+ -0.00000000000000022204460492503126,
+ );
+
+- assert_eq!(fma(-0.992, -0.992, -0.992), -0.00793599999988632,);
++ let result = fma(-0.992, -0.992, -0.992);
++ //force rounding to storage format on x87 to prevent superious errors.
++ #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]force_eval!(result);
++ assert_eq!(result, -0.00793599999988632,);
+ }
+ }
+Index: rust-libm-0.2.1/src/math/pow.rs
+===================================================================
+--- rust-libm-0.2.1.orig/src/math/pow.rs
++++ rust-libm-0.2.1/src/math/pow.rs
+@@ -484,6 +484,8 @@ mod tests {
+ let exp = expected(*val);
+ let res = computed(*val);
+
++ #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]force_eval!(exp);
++ #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]force_eval!(res);
+ assert!(
+ if exp.is_nan() {
+ res.is_nan()
+Index: rust-libm-0.2.1/src/math/sin.rs
+===================================================================
+--- rust-libm-0.2.1.orig/src/math/sin.rs
++++ rust-libm-0.2.1/src/math/sin.rs
+@@ -81,5 +81,7 @@ pub fn sin(x: f64) -> f64 {
+ fn test_near_pi() {
+ let x = f64::from_bits(0x400921fb000FD5DD); // 3.141592026217707
+ let sx = f64::from_bits(0x3ea50d15ced1a4a2); // 6.273720864039205e-7
+- assert_eq!(sin(x), sx);
++ let result = sin(x);
++ #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]force_eval!(result);
++ assert_eq!(result, sx);
+ }
--- /dev/null
+commit 1606eeae5c1a916adb926d2972ab63a781b1b670
+Author: Peter Michael Green <plugwash@debian.org>
+Date: Tue Jan 4 20:38:09 2022 +0000
+
+ only allow x87-specific result in j1f.rs test on x87
+
+diff --git a/src/math/j1f.rs b/src/math/j1f.rs
+index 225b719..775ff2b 100644
+--- a/src/math/j1f.rs
++++ b/src/math/j1f.rs
+@@ -371,8 +371,7 @@ mod tests {
+ fn test_y1f_2002() {
+ //allow slightly different result on x87
+ let res = y1f(2.0000002_f32);
+- if res != -0.10703231_f32 {
+- assert_eq!(res, -0.10703229_f32);
+- }
++ if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) && (res == -0.10703231_f32) { return };
++ assert_eq!(res, -0.10703229_f32);
+ }
+ }
--- /dev/null
+This patch is based on the commit described below, which has
+been submitted as part of https://github.com/rust-lang/libm/pull/249
+adapted for use in the Debian package.
+
+commit 9b6f469d5b3e35f793800da1c58070da2478f76e
+Author: Peter Michael Green <plugwash@debian.org>
+Date: Tue Jan 4 20:51:40 2022 +0000
+
+ allow force_eval! to produce a result and use that result to more explicitly force rounding on x87.
+
+Index: rust-libm-0.2.1/src/math/fma.rs
+===================================================================
+--- rust-libm-0.2.1.orig/src/math/fma.rs
++++ rust-libm-0.2.1/src/math/fma.rs
+@@ -220,7 +220,8 @@ mod tests {
+
+ let result = fma(-0.992, -0.992, -0.992);
+ //force rounding to storage format on x87 to prevent superious errors.
+- #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]force_eval!(result);
++ #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
++ let result = force_eval!(result);
+ assert_eq!(result, -0.00793599999988632,);
+ }
+ }
+Index: rust-libm-0.2.1/src/math/mod.rs
+===================================================================
+--- rust-libm-0.2.1.orig/src/math/mod.rs
++++ rust-libm-0.2.1/src/math/mod.rs
+@@ -1,7 +1,7 @@
+ macro_rules! force_eval {
+ ($e:expr) => {
+ unsafe {
+- ::core::ptr::read_volatile(&$e);
++ ::core::ptr::read_volatile(&$e)
+ }
+ };
+ }
+Index: rust-libm-0.2.1/src/math/pow.rs
+===================================================================
+--- rust-libm-0.2.1.orig/src/math/pow.rs
++++ rust-libm-0.2.1/src/math/pow.rs
+@@ -484,8 +484,10 @@ mod tests {
+ let exp = expected(*val);
+ let res = computed(*val);
+
+- #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]force_eval!(exp);
+- #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]force_eval!(res);
++ #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
++ let exp = force_eval!(exp);
++ #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
++ let res = force_eval!(res);
+ assert!(
+ if exp.is_nan() {
+ res.is_nan()
+Index: rust-libm-0.2.1/src/math/rem_pio2.rs
+===================================================================
+--- rust-libm-0.2.1.orig/src/math/rem_pio2.rs
++++ rust-libm-0.2.1/src/math/rem_pio2.rs
+@@ -53,7 +53,8 @@ pub(crate) fn rem_pio2(x: f64) -> (i32,
+ let tmp = x as f64 * INV_PIO2 + TO_INT;
+ // force rounding of tmp to it's storage format on x87 to avoid
+ // excess precision issues.
+- #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]force_eval!(tmp);
++ #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
++ let tmp = force_eval!(tmp);
+ let f_n = tmp - TO_INT;
+ let n = f_n as i32;
+ let mut r = x - f_n * PIO2_1;
+@@ -195,25 +196,25 @@ mod tests {
+ #[test]
+ fn test_near_pi() {
+ let arg = 3.141592025756836;
+- force_eval!(arg);
++ let arg = force_eval!(arg);
+ assert_eq!(
+ rem_pio2(arg),
+ (2, -6.278329573009626e-7, -2.1125998133974653e-23)
+ );
+ let arg = 3.141592033207416;
+- force_eval!(arg);
++ let arg = force_eval!(arg);
+ assert_eq!(
+ rem_pio2(arg),
+ (2, -6.20382377148128e-7, -2.1125998133974653e-23)
+ );
+ let arg = 3.141592144966125;
+- force_eval!(arg);
++ let arg = force_eval!(arg);
+ assert_eq!(
+ rem_pio2(arg),
+ (2, -5.086236681942706e-7, -2.1125998133974653e-23)
+ );
+ let arg = 3.141592979431152;
+- force_eval!(arg);
++ let arg = force_eval!(arg);
+ assert_eq!(
+ rem_pio2(arg),
+ (2, 3.2584135866119817e-7, -2.1125998133974653e-23)
+Index: rust-libm-0.2.1/src/math/rem_pio2f.rs
+===================================================================
+--- rust-libm-0.2.1.orig/src/math/rem_pio2f.rs
++++ rust-libm-0.2.1/src/math/rem_pio2f.rs
+@@ -46,7 +46,8 @@ pub(crate) fn rem_pio2f(x: f32) -> (i32,
+ let tmp = x64 * INV_PIO2 + TOINT;
+ // force rounding of tmp to it's storage format on x87 to avoid
+ // excess precision issues.
+- #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]force_eval!(tmp);
++ #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
++ let tmp = force_eval!(tmp);
+ let f_n = tmp - TOINT;
+ return (f_n as i32, x64 - f_n * PIO2_1 - f_n * PIO2_1T);
+ }
+Index: rust-libm-0.2.1/src/math/sin.rs
+===================================================================
+--- rust-libm-0.2.1.orig/src/math/sin.rs
++++ rust-libm-0.2.1/src/math/sin.rs
+@@ -82,6 +82,7 @@ fn test_near_pi() {
+ let x = f64::from_bits(0x400921fb000FD5DD); // 3.141592026217707
+ let sx = f64::from_bits(0x3ea50d15ced1a4a2); // 6.273720864039205e-7
+ let result = sin(x);
+- #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]force_eval!(result);
++ #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
++ let result = force_eval!(result);
+ assert_eq!(result, sx);
+ }
--- /dev/null
+This patch contains fixes for round and roundf that are similar
+to those made to other functions in https://github.com/rust-lang/libm/pull/249
+they are not included in the PR because since the latest release
+upstream reimplemented found and roundf in terms of trunc and truncf.
+
+Index: rust-libm-0.2.1.newpatches/src/math/round.rs
+===================================================================
+--- rust-libm-0.2.1.newpatches.orig/src/math/round.rs
++++ rust-libm-0.2.1.newpatches/src/math/round.rs
+@@ -19,7 +19,11 @@ pub fn round(mut x: f64) -> f64 {
+ if i >> 63 != 0 {
+ x = -x;
+ }
+- y = x + TOINT - TOINT - x;
++ // use force_eval to force rounding to storage format on x87.
++ let tmp = x + TOINT;
++ #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
++ let tmp = force_eval!(tmp);
++ y = tmp - TOINT - x;
+ if y > 0.5 {
+ y = y + x - 1.0;
+ } else if y <= -0.5 {
+Index: rust-libm-0.2.1.newpatches/src/math/roundf.rs
+===================================================================
+--- rust-libm-0.2.1.newpatches.orig/src/math/roundf.rs
++++ rust-libm-0.2.1.newpatches/src/math/roundf.rs
+@@ -18,7 +18,11 @@ pub fn roundf(mut x: f32) -> f32 {
+ if i >> 31 != 0 {
+ x = -x;
+ }
+- y = x + TOINT - TOINT - x;
++ // use force_eval to force rounding to storage format on x87.
++ let tmp = x + TOINT;
++ #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
++ let tmp = force_eval!(tmp);
++ y = tmp - TOINT - x;
+ if y > 0.5f32 {
+ y = y + x - 1.0;
+ } else if y <= -0.5f32 {