From 306764b0914ac7f16dca069947d18d6b9659e717 Mon Sep 17 00:00:00 2001 From: Paolo Teti Date: Fri, 9 Feb 2018 17:13:45 +0100 Subject: [PATCH 1/2] Fix issue extending f32::MIN/MAX to f64 and improve testcrate. I was able to trigger an issue extending f32::MAX or f32::MIN to a f64. Issue was not triggered by `testcrate` mainly because f32::MAX/MIN are not in the list of special values to generate. This PR fix the issue and improve `testcrate` adding MAX/MIN/MIN_POSITIVE in the list of special values. --- src/float/extend.rs | 2 +- testcrate/build.rs | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/float/extend.rs b/src/float/extend.rs index 1abb23c..a71b7a1 100644 --- a/src/float/extend.rs +++ b/src/float/extend.rs @@ -41,7 +41,7 @@ fn extend(a: F) -> R where let abs_dst: R::Int = a_abs.cast(); let bias_dst: R::Int = exp_bias_delta.cast(); abs_result = abs_dst.wrapping_shl(sign_bits_delta); - abs_result |= bias_dst.wrapping_shl(dst_sign_bits); + abs_result += bias_dst.wrapping_shl(dst_sign_bits); } else if a_abs >= src_infinity { // a is NaN or infinity. // Conjure the result by beginning with infinity, then setting the qNaN diff --git a/testcrate/build.rs b/testcrate/build.rs index 9269983..40cc1db 100644 --- a/testcrate/build.rs +++ b/testcrate/build.rs @@ -703,6 +703,9 @@ macro_rules! gen_float { // Special values *rng.choose(&[-0.0, 0.0, + ::std::$fty::MIN, + ::std::$fty::MIN_POSITIVE, + ::std::$fty::MAX, ::std::$fty::NAN, ::std::$fty::INFINITY, -::std::$fty::INFINITY]) @@ -754,6 +757,9 @@ macro_rules! gen_large_float { // Special values *rng.choose(&[-0.0, 0.0, + ::std::$fty::MIN, + ::std::$fty::MIN_POSITIVE, + ::std::$fty::MAX, ::std::$fty::NAN, ::std::$fty::INFINITY, -::std::$fty::INFINITY]) From 2cb290afa38fcb11ff7aa11c9eb33b29b93c325f Mon Sep 17 00:00:00 2001 From: Paolo Teti Date: Fri, 9 Feb 2018 20:35:55 +0100 Subject: [PATCH 2/2] Fix __subsf3 and __subdf3 on x86 Be sure to do not mix hard-float and soft-float calls. Disassembled code show exactly this. So replace add with an explicit call to __addsf3/__adddf3 This seems the root cause of some sporadic failures. --- src/float/sub.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/float/sub.rs b/src/float/sub.rs index c2791bf..2afb140 100644 --- a/src/float/sub.rs +++ b/src/float/sub.rs @@ -1,14 +1,16 @@ use float::Float; +use float::add::__addsf3; +use float::add::__adddf3; intrinsics! { #[arm_aeabi_alias = __aeabi_fsub] pub extern "C" fn __subsf3(a: f32, b: f32) -> f32 { - a + f32::from_repr(b.repr() ^ f32::SIGN_MASK) + __addsf3(a, f32::from_repr(b.repr() ^ f32::SIGN_MASK)) } #[arm_aeabi_alias = __aeabi_dsub] pub extern "C" fn __subdf3(a: f64, b: f64) -> f64 { - a + f64::from_repr(b.repr() ^ f64::SIGN_MASK) + __adddf3(a, f64::from_repr(b.repr() ^ f64::SIGN_MASK)) } #[cfg(target_arch = "arm")]