-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Miri: non-deterministic floating point operations in foreign_items
#143906
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -304,7 +304,7 @@ impl f32 { | |
/// ``` | ||
/// let x = 2.0_f32; | ||
/// let abs_difference = (x.powi(2) - (x * x)).abs(); | ||
/// assert!(abs_difference <= 1e-5); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// | ||
/// assert_eq!(f32::powi(f32::NAN, 0), 1.0); | ||
/// ``` | ||
|
@@ -328,7 +328,7 @@ impl f32 { | |
/// ``` | ||
/// let x = 2.0_f32; | ||
/// let abs_difference = (x.powf(2.0) - (x * x)).abs(); | ||
/// assert!(abs_difference <= 1e-5); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// | ||
/// assert_eq!(f32::powf(1.0, f32::NAN), 1.0); | ||
/// assert_eq!(f32::powf(f32::NAN, 0.0), 1.0); | ||
|
@@ -388,7 +388,7 @@ impl f32 { | |
/// // ln(e) - 1 == 0 | ||
/// let abs_difference = (e.ln() - 1.0).abs(); | ||
/// | ||
/// assert!(abs_difference <= 1e-6); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -413,7 +413,7 @@ impl f32 { | |
/// // 2^2 - 4 == 0 | ||
/// let abs_difference = (f.exp2() - 4.0).abs(); | ||
/// | ||
/// assert!(abs_difference <= 1e-5); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -442,7 +442,7 @@ impl f32 { | |
/// // ln(e) - 1 == 0 | ||
/// let abs_difference = (e.ln() - 1.0).abs(); | ||
/// | ||
/// assert!(abs_difference <= 1e-6); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
/// | ||
/// Non-positive values: | ||
|
@@ -479,7 +479,7 @@ impl f32 { | |
/// // log5(5) - 1 == 0 | ||
/// let abs_difference = (five.log(5.0) - 1.0).abs(); | ||
/// | ||
/// assert!(abs_difference <= 1e-6); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
/// | ||
/// Non-positive values: | ||
|
@@ -512,7 +512,7 @@ impl f32 { | |
/// // log2(2) - 1 == 0 | ||
/// let abs_difference = (two.log2() - 1.0).abs(); | ||
/// | ||
/// assert!(abs_difference <= 1e-6); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
/// | ||
/// Non-positive values: | ||
|
@@ -545,7 +545,7 @@ impl f32 { | |
/// // log10(10) - 1 == 0 | ||
/// let abs_difference = (ten.log10() - 1.0).abs(); | ||
/// | ||
/// assert!(abs_difference <= 1e-6); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
/// | ||
/// Non-positive values: | ||
|
@@ -582,8 +582,8 @@ impl f32 { | |
/// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs(); | ||
/// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs(); | ||
/// | ||
/// assert!(abs_difference_x <= f32::EPSILON); | ||
/// assert!(abs_difference_y <= f32::EPSILON); | ||
/// assert!(abs_difference_x <= 1e-4); | ||
/// assert!(abs_difference_y <= 1e-4); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -621,7 +621,7 @@ impl f32 { | |
/// // x^(1/3) - 2 == 0 | ||
/// let abs_difference = (x.cbrt() - 2.0).abs(); | ||
/// | ||
/// assert!(abs_difference <= f32::EPSILON); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -652,7 +652,7 @@ impl f32 { | |
/// // sqrt(x^2 + y^2) | ||
/// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs(); | ||
/// | ||
/// assert!(abs_difference <= 1e-6); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -676,7 +676,7 @@ impl f32 { | |
/// | ||
/// let abs_difference = (x.sin() - 1.0).abs(); | ||
/// | ||
/// assert!(abs_difference <= 1e-6); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -700,7 +700,7 @@ impl f32 { | |
/// | ||
/// let abs_difference = (x.cos() - 1.0).abs(); | ||
/// | ||
/// assert!(abs_difference <= 1e-6); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -725,7 +725,7 @@ impl f32 { | |
/// let x = std::f32::consts::FRAC_PI_4; | ||
/// let abs_difference = (x.tan() - 1.0).abs(); | ||
/// | ||
/// assert!(abs_difference <= f32::EPSILON); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -784,7 +784,7 @@ impl f32 { | |
/// // acos(cos(pi/4)) | ||
/// let abs_difference = (f.cos().acos() - std::f32::consts::FRAC_PI_4).abs(); | ||
/// | ||
/// assert!(abs_difference <= 1e-6); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
#[doc(alias = "arccos")] | ||
#[rustc_allow_incoherent_impl] | ||
|
@@ -813,7 +813,7 @@ impl f32 { | |
/// // atan(tan(1)) | ||
/// let abs_difference = (f.tan().atan() - 1.0).abs(); | ||
/// | ||
/// assert!(abs_difference <= f32::EPSILON); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
#[doc(alias = "arctan")] | ||
#[rustc_allow_incoherent_impl] | ||
|
@@ -854,8 +854,8 @@ impl f32 { | |
/// let abs_difference_1 = (y1.atan2(x1) - (-std::f32::consts::FRAC_PI_4)).abs(); | ||
/// let abs_difference_2 = (y2.atan2(x2) - (3.0 * std::f32::consts::FRAC_PI_4)).abs(); | ||
/// | ||
/// assert!(abs_difference_1 <= f32::EPSILON); | ||
/// assert!(abs_difference_2 <= f32::EPSILON); | ||
/// assert!(abs_difference_1 <= 1e-4); | ||
/// assert!(abs_difference_2 <= 1e-4); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -884,8 +884,8 @@ impl f32 { | |
/// let abs_difference_0 = (f.0 - x.sin()).abs(); | ||
/// let abs_difference_1 = (f.1 - x.cos()).abs(); | ||
/// | ||
/// assert!(abs_difference_0 <= 1e-6); | ||
/// assert!(abs_difference_1 <= 1e-6); | ||
/// assert!(abs_difference_0 <= 1e-4); | ||
/// assert!(abs_difference_1 <= 1e-4); | ||
/// ``` | ||
#[doc(alias = "sincos")] | ||
#[rustc_allow_incoherent_impl] | ||
|
@@ -914,7 +914,7 @@ impl f32 { | |
/// let approx = x + x * x / 2.0; | ||
/// let abs_difference = (x.exp_m1() - approx).abs(); | ||
/// | ||
/// assert!(abs_difference < 1e-10); | ||
/// assert!(abs_difference < 1e-4); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -945,7 +945,7 @@ impl f32 { | |
/// let approx = x - x * x / 2.0; | ||
/// let abs_difference = (x.ln_1p() - approx).abs(); | ||
/// | ||
/// assert!(abs_difference < 1e-10); | ||
/// assert!(abs_difference < 1e-4); | ||
/// ``` | ||
/// | ||
/// Out-of-range values: | ||
|
@@ -982,7 +982,7 @@ impl f32 { | |
/// let g = ((e * e) - 1.0) / (2.0 * e); | ||
/// let abs_difference = (f - g).abs(); | ||
/// | ||
/// assert!(abs_difference <= f32::EPSILON); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -1012,7 +1012,7 @@ impl f32 { | |
/// let abs_difference = (f - g).abs(); | ||
/// | ||
/// // Same result | ||
/// assert!(abs_difference <= f32::EPSILON); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -1042,7 +1042,7 @@ impl f32 { | |
/// let g = (1.0 - e.powi(-2)) / (1.0 + e.powi(-2)); | ||
/// let abs_difference = (f - g).abs(); | ||
/// | ||
/// assert!(abs_difference <= f32::EPSILON); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -1067,7 +1067,7 @@ impl f32 { | |
/// | ||
/// let abs_difference = (f - x).abs(); | ||
/// | ||
/// assert!(abs_difference <= 1e-7); | ||
/// assert!(abs_difference <= 1e-4); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's this one that failed, not the one I commented here https://github.com/rust-lang/rust/pull/143906/files#r2225770166
Agreed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one might be amplifying an underlying error introduced in But 1000 tests should still be enough for all practical purposes... strange. |
||
/// ``` | ||
#[doc(alias = "arcsinh")] | ||
#[rustc_allow_incoherent_impl] | ||
|
@@ -1095,7 +1095,7 @@ impl f32 { | |
/// | ||
/// let abs_difference = (f - x).abs(); | ||
/// | ||
/// assert!(abs_difference <= 1e-6); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
#[doc(alias = "arccosh")] | ||
#[rustc_allow_incoherent_impl] | ||
|
@@ -1125,7 +1125,7 @@ impl f32 { | |
/// | ||
/// let abs_difference = (f - e).abs(); | ||
/// | ||
/// assert!(abs_difference <= 1e-5); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
#[doc(alias = "arctanh")] | ||
#[rustc_allow_incoherent_impl] | ||
|
@@ -1153,7 +1153,7 @@ impl f32 { | |
/// | ||
/// let abs_difference = (x.gamma() - 24.0).abs(); | ||
/// | ||
/// assert!(abs_difference <= f32::EPSILON); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -1248,7 +1248,7 @@ impl f32 { | |
/// let one = x.erf() + x.erfc(); | ||
/// let abs_difference = (one - 1.0).abs(); | ||
/// | ||
/// assert!(abs_difference <= f32::EPSILON); | ||
/// assert!(abs_difference <= 1e-4); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -304,7 +304,7 @@ impl f64 { | |
/// ``` | ||
/// let x = 2.0_f64; | ||
/// let abs_difference = (x.powi(2) - (x * x)).abs(); | ||
/// assert!(abs_difference <= 1e-14); | ||
/// assert!(abs_difference <= 1e-10); | ||
/// | ||
/// assert_eq!(f64::powi(f64::NAN, 0), 1.0); | ||
/// ``` | ||
|
@@ -328,7 +328,7 @@ impl f64 { | |
/// ``` | ||
/// let x = 2.0_f64; | ||
/// let abs_difference = (x.powf(2.0) - (x * x)).abs(); | ||
/// assert!(abs_difference <= 1e-14); | ||
/// assert!(abs_difference <= 1e-10); | ||
/// | ||
/// assert_eq!(f64::powf(1.0, f64::NAN), 1.0); | ||
/// assert_eq!(f64::powf(f64::NAN, 0.0), 1.0); | ||
|
@@ -725,7 +725,7 @@ impl f64 { | |
/// let x = std::f64::consts::FRAC_PI_4; | ||
/// let abs_difference = (x.tan() - 1.0).abs(); | ||
/// | ||
/// assert!(abs_difference < 1e-14); | ||
/// assert!(abs_difference < 1e-10); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -754,7 +754,7 @@ impl f64 { | |
/// // asin(sin(pi/2)) | ||
/// let abs_difference = (f.sin().asin() - std::f64::consts::FRAC_PI_2).abs(); | ||
/// | ||
/// assert!(abs_difference < 1e-7); | ||
/// assert!(abs_difference < 1e-5); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This failed because of the double operations, but it's weird this one is so unprecise when running under miri, while others like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried 1000 seeds and 1e-7 always worked. Why did you reduce to 1e-5? (1e-8 failed quickly.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In contrast, we are evaluating There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we should change the test to an area where asin is more stable -- like pi/4, which the other 2 tests are already using? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I commented this on the wrong test, but you're last 2 replies apply to that test as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, but you did change this one to 1e-5... why? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is not a good indicator; I also did this check, but it still failed in CI. Thus, I changed it based on the assumption that this one would fail similarly in CI. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we hit a 1/1000 event in CI the first try, that is worth further investigation as it indicates something rather unlikely. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm sorry, I was a little fast in my reply. The test that failed in CI was |
||
/// ``` | ||
#[doc(alias = "arcsin")] | ||
#[rustc_allow_incoherent_impl] | ||
|
@@ -914,7 +914,7 @@ impl f64 { | |
/// let approx = x + x * x / 2.0; | ||
/// let abs_difference = (x.exp_m1() - approx).abs(); | ||
/// | ||
/// assert!(abs_difference < 1e-20); | ||
/// assert!(abs_difference < 1e-10); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -945,7 +945,7 @@ impl f64 { | |
/// let approx = x - x * x / 2.0; | ||
/// let abs_difference = (x.ln_1p() - approx).abs(); | ||
/// | ||
/// assert!(abs_difference < 1e-20); | ||
/// assert!(abs_difference < 1e-10); | ||
/// ``` | ||
/// | ||
/// Out-of-range values: | ||
|
@@ -1153,7 +1153,7 @@ impl f64 { | |
/// | ||
/// let abs_difference = (x.gamma() - 24.0).abs(); | ||
/// | ||
/// assert!(abs_difference <= f64::EPSILON); | ||
/// assert!(abs_difference <= 1e-10); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
@@ -1248,7 +1248,7 @@ impl f64 { | |
/// let one = x.erf() + x.erfc(); | ||
/// let abs_difference = (one - 1.0).abs(); | ||
/// | ||
/// assert!(abs_difference <= f64::EPSILON); | ||
/// assert!(abs_difference <= 1e-10); | ||
/// ``` | ||
#[rustc_allow_incoherent_impl] | ||
#[must_use = "method returns a new number and does not mutate the original value"] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1e-5 didn't work for f32, right? Is there just a single test that is the culprit, or is it a bunch of them?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
asinh
failed, but it's getting confusing having 3 different constants for these tests, so I wanted to unify them to one. Side note: a single f32 test has 1e-3.Maybe if we change that test as well, I can change them back to their limits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me know what you and @tgross35 prefer. Having a single constant that works for them all, or individual limits, or something else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense that operations which are direct wrappers around a libm functions, like
sin
, expect higher precision than things likeasinh
. So I'd say optimize for minimizing the diff here.And yeah, please change all the
asin
tests to use FRAC_PI_4 to avoid instability aroundasin(1)
.