-
Notifications
You must be signed in to change notification settings - Fork 454
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
[interpreter] f32.convert_u/i64 and f32_convert_s/i64 have incorrect rounding #421
Comments
Here's another interesting boundary case:
|
Another signed one:
|
Ah, the signed implementation is also using double rounding. Here's a more comprehensive collection of boundary condition testcases. For both unsigned and signed, for the minimum value, the maximum value in the low half of the domain, the minimum value in the high half of the domain, and the maximum value, where double rounding is observable:
|
@sunfishcode, @bnjbvr, has this been addressed? Can this issue be closed? |
AFAIK, it hasn't been addressed, since there is no easy way to fix it in Ocaml atm, short of implementing f32 ourselves. Let's leave it open. |
I agree. Here's a standalone wast testcase of the tests listed above, updated for the new operator names, which fails in the current spec interpreter but which should pass, and does pass in Wasmtime, the wabt interpreter, and probably other implementations. (module
(func (export "f32.convert_i32_s") (param $x i32) (result f32) (f32.convert_i32_s (local.get $x)))
(func (export "f32.convert_i64_s") (param $x i64) (result f32) (f32.convert_i64_s (local.get $x)))
(func (export "f64.convert_i32_s") (param $x i32) (result f64) (f64.convert_i32_s (local.get $x)))
(func (export "f64.convert_i64_s") (param $x i64) (result f64) (f64.convert_i64_s (local.get $x)))
(func (export "f32.convert_i32_u") (param $x i32) (result f32) (f32.convert_i32_u (local.get $x)))
(func (export "f32.convert_i64_u") (param $x i64) (result f32) (f32.convert_i64_u (local.get $x)))
(func (export "f64.convert_i32_u") (param $x i32) (result f64) (f64.convert_i32_u (local.get $x)))
(func (export "f64.convert_i64_u") (param $x i64) (result f64) (f64.convert_i64_u (local.get $x)))
)
(assert_return (invoke "f32.convert_i64_u" (i64.const 0x0020000020000001)) (f32.const 0x1.000002p+53))
(assert_return (invoke "f32.convert_i64_u" (i64.const 0x7fffffbfffffffff)) (f32.const 0x1.fffffep+62))
(assert_return (invoke "f32.convert_i64_u" (i64.const 0x8000008000000001)) (f32.const 0x1.000002p+63))
(assert_return (invoke "f32.convert_i64_u" (i64.const 0xfffffe8000000001)) (f32.const 0x1.fffffep+63))
(assert_return (invoke "f32.convert_i64_s" (i64.const 0x8000004000000001)) (f32.const -0x1.fffffep+62))
(assert_return (invoke "f32.convert_i64_s" (i64.const 0xffdfffffdfffffff)) (f32.const -0x1.000002p+53))
(assert_return (invoke "f32.convert_i64_s" (i64.const 0x0020000020000001)) (f32.const 0x1.000002p+53))
(assert_return (invoke "f32.convert_i64_s" (i64.const 0x7fffff4000000001)) (f32.const 0x1.fffffep+62)) The spec interpreter prints:
|
I think I have a simple fix for this, see #1021. @sunfishcode, PTAL. |
[test] Add tests for packed struct fields
The implementation of f32.convert_u/i64 has incorrect rounding in some cases. For example, these tests should pass but currently fail:
A fix analogous to #420 is not sufficient, because OCaml lacks 32-bit float types, so it would round to 64-bit float first, then round to 32-bit float in a separate step, leading to incorrect rounding. For example, the above tests still fail.
The text was updated successfully, but these errors were encountered: