about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorOrson Peters <orsonpeters@gmail.com>2021-11-29 12:10:09 +0100
committerUrgau <urgau@numericable.fr>2022-08-15 12:33:00 +0200
commitde757e8a98ce0a4efe91f2f46e93abe1c197bcdf (patch)
tree8acd671568ccc0ecc29965150fb01e569c4acdbd /library/std/src
parent3241bbcbc792c0391ed8ed2772ba02b4c9cae67d (diff)
downloadrust-de757e8a98ce0a4efe91f2f46e93abe1c197bcdf.tar.gz
rust-de757e8a98ce0a4efe91f2f46e93abe1c197bcdf.zip
Ensure NaN references values go through function boundary for next_up/down.
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/f32/tests.rs24
-rw-r--r--library/std/src/f64/tests.rs24
2 files changed, 36 insertions, 12 deletions
diff --git a/library/std/src/f32/tests.rs b/library/std/src/f32/tests.rs
index 07b9ff3a789..7a2f9bd4878 100644
--- a/library/std/src/f32/tests.rs
+++ b/library/std/src/f32/tests.rs
@@ -308,12 +308,18 @@ fn test_next_up() {
     let smallest_normal = f32::from_bits(0x0080_0000);
 
     // Check that NaNs roundtrip.
+    // Because x87 can lose NaN bits when passed through a function, ensure the reference value
+    // also passes through a function boundary.
+    #[inline(never)]
+    fn identity(x: f32) -> f32 {
+        crate::hint::black_box(x)
+    }
     let nan0 = f32::NAN;
     let nan1 = f32::from_bits(f32::NAN.to_bits() ^ 0x002a_aaaa);
     let nan2 = f32::from_bits(f32::NAN.to_bits() ^ 0x0055_5555);
-    assert_eq!(nan0.next_up().to_bits(), nan0.to_bits());
-    assert_eq!(nan1.next_up().to_bits(), nan1.to_bits());
-    assert_eq!(nan2.next_up().to_bits(), nan2.to_bits());
+    assert_eq!(nan0.next_up().to_bits(), identity(nan0).to_bits());
+    assert_eq!(nan1.next_up().to_bits(), identity(nan1).to_bits());
+    assert_eq!(nan2.next_up().to_bits(), identity(nan2).to_bits());
 
     assert_eq!(f32::NEG_INFINITY.next_up(), f32::MIN);
     assert_eq!(f32::MIN.next_up(), -max_down);
@@ -339,12 +345,18 @@ fn test_next_down() {
     let smallest_normal = f32::from_bits(0x0080_0000);
 
     // Check that NaNs roundtrip.
+    // Because x87 can lose NaN bits when passed through a function, ensure the reference value
+    // also passes through a function boundary.
+    #[inline(never)]
+    fn identity(x: f32) -> f32 {
+        crate::hint::black_box(x)
+    }
     let nan0 = f32::NAN;
     let nan1 = f32::from_bits(f32::NAN.to_bits() ^ 0x002a_aaaa);
     let nan2 = f32::from_bits(f32::NAN.to_bits() ^ 0x0055_5555);
-    assert_eq!(nan0.next_down().to_bits(), nan0.to_bits());
-    assert_eq!(nan1.next_down().to_bits(), nan1.to_bits());
-    assert_eq!(nan2.next_down().to_bits(), nan2.to_bits());
+    assert_eq!(nan0.next_down().to_bits(), identity(nan0).to_bits());
+    assert_eq!(nan1.next_down().to_bits(), identity(nan1).to_bits());
+    assert_eq!(nan2.next_down().to_bits(), identity(nan2).to_bits());
 
     assert_eq!(f32::NEG_INFINITY.next_down(), f32::NEG_INFINITY);
     assert_eq!(f32::MIN.next_down(), f32::NEG_INFINITY);
diff --git a/library/std/src/f64/tests.rs b/library/std/src/f64/tests.rs
index cf46ffcffcf..2524bfe8b99 100644
--- a/library/std/src/f64/tests.rs
+++ b/library/std/src/f64/tests.rs
@@ -298,12 +298,18 @@ fn test_next_up() {
     let smallest_normal = f64::from_bits(0x0010_0000_0000_0000);
 
     // Check that NaNs roundtrip.
+    // Because x87 can lose NaN bits when passed through a function, ensure the reference value
+    // also passes through a function boundary.
+    #[inline(never)]
+    fn identity(x: f64) -> f64 {
+        crate::hint::black_box(x)
+    }
     let nan0 = f64::NAN;
     let nan1 = f64::from_bits(f64::NAN.to_bits() ^ 0x000a_aaaa_aaaa_aaaa);
     let nan2 = f64::from_bits(f64::NAN.to_bits() ^ 0x0005_5555_5555_5555);
-    assert_eq!(nan0.next_up().to_bits(), nan0.to_bits());
-    assert_eq!(nan1.next_up().to_bits(), nan1.to_bits());
-    assert_eq!(nan2.next_up().to_bits(), nan2.to_bits());
+    assert_eq!(nan0.next_up().to_bits(), identity(nan0).to_bits());
+    assert_eq!(nan1.next_up().to_bits(), identity(nan1).to_bits());
+    assert_eq!(nan2.next_up().to_bits(), identity(nan2).to_bits());
 
     assert_eq!(f64::NEG_INFINITY.next_up(), f64::MIN);
     assert_eq!(f64::MIN.next_up(), -max_down);
@@ -329,12 +335,18 @@ fn test_next_down() {
     let smallest_normal = f64::from_bits(0x0010_0000_0000_0000);
 
     // Check that NaNs roundtrip.
+    // Because x87 can lose NaN bits when passed through a function, ensure the reference value
+    // also passes through a function boundary.
+    #[inline(never)]
+    fn identity(x: f64) -> f64 {
+        crate::hint::black_box(x)
+    }
     let nan0 = f64::NAN;
     let nan1 = f64::from_bits(f64::NAN.to_bits() ^ 0x000a_aaaa_aaaa_aaaa);
     let nan2 = f64::from_bits(f64::NAN.to_bits() ^ 0x0005_5555_5555_5555);
-    assert_eq!(nan0.next_down().to_bits(), nan0.to_bits());
-    assert_eq!(nan1.next_down().to_bits(), nan1.to_bits());
-    assert_eq!(nan2.next_down().to_bits(), nan2.to_bits());
+    assert_eq!(nan0.next_down().to_bits(), identity(nan0).to_bits());
+    assert_eq!(nan1.next_down().to_bits(), identity(nan1).to_bits());
+    assert_eq!(nan2.next_down().to_bits(), identity(nan2).to_bits());
 
     assert_eq!(f64::NEG_INFINITY.next_down(), f64::NEG_INFINITY);
     assert_eq!(f64::MIN.next_down(), f64::NEG_INFINITY);