From dc0ba7836528b7d8720b868e331a378ceaf8fa95 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Fri, 21 Jul 2023 15:44:15 -0400 Subject: [PATCH] Don't require strict equality when subnormals are flushed --- crates/test_helpers/Cargo.toml | 7 +++---- crates/test_helpers/src/biteq.rs | 2 ++ crates/test_helpers/src/lib.rs | 13 +++++++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/crates/test_helpers/Cargo.toml b/crates/test_helpers/Cargo.toml index 1d2bc8b519a..bd481db6bac 100644 --- a/crates/test_helpers/Cargo.toml +++ b/crates/test_helpers/Cargo.toml @@ -4,10 +4,9 @@ version = "0.1.0" edition = "2021" publish = false -[dependencies.proptest] -version = "0.10" -default-features = false -features = ["alloc"] +[dependencies] +float_eq = "1.0" +proptest = { version = "0.10", default-features = false, features = ["alloc"] } [features] all_lane_counts = [] diff --git a/crates/test_helpers/src/biteq.rs b/crates/test_helpers/src/biteq.rs index 7d91260d838..515eaf1c048 100644 --- a/crates/test_helpers/src/biteq.rs +++ b/crates/test_helpers/src/biteq.rs @@ -40,6 +40,8 @@ impl BitEq for $type { fn biteq(&self, other: &Self) -> bool { if self.is_nan() && other.is_nan() { true // exact nan bits don't matter + } else if crate::flush_subnormals::() { + self.to_bits() == other.to_bits() || float_eq::float_eq!(self, other, abs <= 2. * <$type>::EPSILON) } else { self.to_bits() == other.to_bits() } diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs index b26cdc311a2..1b98bccf706 100644 --- a/crates/test_helpers/src/lib.rs +++ b/crates/test_helpers/src/lib.rs @@ -6,6 +6,19 @@ #[macro_use] pub mod biteq; +/// Indicates if subnormal floats are flushed to zero. +pub fn flush_subnormals() -> bool { + let is_f32 = core::mem::size_of::() == 4; + let ppc_flush = is_f32 + && cfg!(all( + target_arch = "powerpc64", + target_endian = "big", + not(target_feature = "vsx") + )); + let arm_flush = is_f32 && cfg!(all(target_arch = "arm", target_feature = "neon")); + ppc_flush || arm_flush +} + /// Specifies the default strategy for testing a type. /// /// This strategy should be what "makes sense" to test.