-
Notifications
You must be signed in to change notification settings - Fork 787
Interpreter: Don't change NaN bits when dividing by 1 #2958
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
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Huh, this fails a spec test, ;; Test that x/1.0 is not folded to x.
(module
(func (export "f32.no_fold_div_one") (param $x f32) (result f32)
(f32.div (local.get $x) (f32.const 1.0)))
(func (export "f64.no_fold_div_one") (param $x f64) (result f64)
(f64.div (local.get $x) (f64.const 1.0)))
)
(assert_return (invoke "f32.no_fold_div_one" (f32.const nan:0x200000)) (f32.const nan:0x600000))
(assert_return (invoke "f64.no_fold_div_one" (f64.const nan:0x4000000000000)) (f64.const nan:0xc000000000000)) Does anyone understand what that test is doing? I'm puzzled by the nan bits change. It seems I'm missing something important here. |
Ah, the spec test has been fixed in upstream, to (assert_return (invoke "f32.no_fold_div_one" (f32.const nan:0x200000)) (f32.const nan:arithmetic))
(assert_return (invoke "f64.no_fold_div_one" (f64.const nan:0x4000000000000)) (f64.const nan:arithmetic)) We don't support that new test notation here, but anyhow I'll just remove that particular test, as the new test added here is even stricter. |
tlively
approved these changes
Jul 15, 2020
Co-authored-by: Thomas Lively <7121787+tlively@users.noreply.github.com>
kripken
added a commit
that referenced
this pull request
Sep 2, 2020
kripken
added a commit
that referenced
this pull request
Sep 9, 2020
Similar to #2958, but for multiplication. I thought this was limited only to division (it doesn't happen for addition, for example), but the fuzzer found that it does indeed happen for multiplication as well. Overall these are kind of workarounds for the interpreter doing normal f32/f64 multiplications using the host CPU, so we pick up any oddness of its NaN behavior. Using soft float might be safer (but much slower).
Merged
kripken
added a commit
that referenced
this pull request
Sep 30, 2020
Similar to clang and gcc, --fast-math makes us ignore corner cases of floating-point math like NaN changes and (not done yet) lack of associativity and so forth. In the future we may want to have separate fast math flags for each specific thing, like gcc and clang do. This undoes some changes (#2958 and #3096) where we assumed it was ok to not change NaN bits, but @binji corrected us. We can only do such things in fast math mode. This puts those optimizations behind that flag, adds tests for it, and restores the interpreter to the simpler code from before with no special cases.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
It's valid to change NaN bits in that case per the wasm spec, but
if we do so then fuzz testcases will fail on the optimization of
nan:foo / 1 => nan:foo
That is, it is ok to leave the bits as they are, and if we do that then
we are consistent with the simple and valid optimization of removing
a divide by 1.
Found by the fuzzer - looks like on x64 on some float32 NaNs,
the bits will actually change (see the testcase). I've seen this on
two machines consistently, so it's normal apparently.