-
Notifications
You must be signed in to change notification settings - Fork 13.5k
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?
Miri: non-deterministic floating point operations in foreign_items
#143906
Conversation
…ests. atan(+-INF, -INF) is not tested in this commit
The Miri subtree was changed cc @rust-lang/miri |
There are some holes in the behaviour of some operations, because I did not know how I could efficiently handle them, I'll mark them and add some explanation. Also, |
"atan2f" | "atan2" => val.clamp(pi.neg(), pi), | ||
|
||
// FIXME: According to Wolfram Alpha, the range of ln(gamma) is [-0.121486, +INF]. What to do? | ||
"lgammaf_r" | "lgamma_r" => val, |
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.
Do I make a method in IeeeExt
trait that gives this exact value, or?
Something like:
fn lgamma_min_output() -> IeeeFloat<S>{ ... }
/// # Note | ||
/// | ||
/// For `powif*` operations of the form `(SNaN)^(±0)` we follow the same behaviour as `powf*`, see [`fixed_float_value`]. | ||
fn fixed_float_int_value<S: Semantics>( |
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.
ldexp
also takes an i32
as the second argument, is this change and name good?
|
||
//atan2(±∞, −∞) = ±3π/4 | ||
("atan2f" | "atan2", [x, y]) if x.is_infinite() && y.is_neg_infinity() => | ||
(pi_over_4 * three).value.copy_sign(*x), |
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 don't know if this will give exactly 3π/4
. Should I add a function to IeeeExt
for this? These will be hex bytes...
|
||
// atan2(±∞, −∞) = ±3π/4 | ||
// assert_eq!($float_type::atan2(INFINITY, NEG_INFINITY), 3.0 * FRAC_PI_4, "atan2(+∞, −∞) = 3π/4"); | ||
// assert_eq!($float_type::atan2(NEG_INFINITY, NEG_INFINITY), -3.0 * FRAC_PI_4, "atan2(-∞, −∞) = -3π/4"); |
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.
This 3.0 * FRAC_PI_4
will never be exactly equal to the operation mentioned in comment above. Use explicit bytes here as well, or is there a cleaner way?
Tested this repeatedly.
let pi = IeeeFloat::<S>::pi(); | ||
let pi_over_2 = IeeeFloat::<S>::frac_pi_2(); | ||
|
||
// Exclusive ranges are made using next_up/next_down. |
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 actually don't know if this is correct, but I assume so :).
|
||
// erfc(+INF) = 0 | ||
// REVIEW/HELP: for some reason the tests fail because erfc(+INF) = 1e-45. Which is weird because | ||
// no error can be applied to 0. Checked and this does not happen without Miri. |
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 have no idea why this is, was stuck on this for like half an hour before I gave up.
Part of rust-lang/miri/#3555, this pr does the
foreign_items
work.Some things have changed since #138062 and #142514. I moved the "helpers" used for creating fixed outputs and clamping operations to their defined ranges to
helpers.rs
. These are now also extended to handle the floating-point operations inforeign_items
. Tests inmiri/tests/float.rs
were changed/added.Failing tests in
std
were extracted, run under miri with-Zmiri-many-seeds=0..1000
and changed accordingly. Double checked with-Zmiri-many-seeds
.I noticed that the C standard doesn't specify the output ranges for all of its mathematical operations; it just specifies them as:
So I used Wolfram|Alpha.