afonso360 opened issue #6961:
:wave: Hey,
This is the last remaining SIMD test that is disabled for RISC-V. I'm fairly sure that the RISC-V backend implements a spec compliant implementation of these instructions but I'd like to confirm it.
Test Case
The original test is the following:
;; from #3327 (module (func (result i32) v128.const i32x4 0xffffffff 0x80bfffff 0x80bf0a0a 0x80bf0a0a f64x2.promote_low_f32x4 v128.not v128.not v128.not v128.not v128.not v128.not v128.not v128.const i32x4 0 0 0 0 f64x2.gt v128.not i64x2.bitmask) (export "" (func 0))) (assert_return (invoke "") (i32.const 0))
Steps to Reproduce
cargo run --target=riscv64gc-unknown-linux-gnu -- wast --disable-cache ./tests/misc_testsuite/simd/issue_3327_bnot_lowering.wast
Expected Results
The test to pass
Actual Results
RISC-V fails.
Versions and Environment
Wasmtime version or commit: main
Operating system: Linux
Architecture: RISC-V
Extra Info
I've reduced the above input down to following clif test:
test interpret test run target riscv64gc has_v target x86_64 function %a(i64) -> f64 fast { const0 = 0x80bf0a0a80bf0a0a80bfffffffffffff block0(v1: i64): v3 = vconst.f32x4 const0 v5 = fvpromote_low v3 v6 = extractlane v5, 0 return v6 } ;; X86_64 passes this ; run: %a(0) == -NaN:0x7ffffe0000000 ;; RISCV64 passes this ; run: %a(0) == NaN
RISC-V returns a Positive Canonical NaN from
fvpromote_low
. While X86 keeps the NaN as negative (and preserves payload bits). In the original test case the NaNs are then compared to check if they are negative, this passes on x86, but not on RISC-V.The docs on
fvpromote_low
don't specify what the correct behaviour here is. So I've looked at the NaN Propagation section of the WASM specification where it states:When the result of a floating-point operator other than
fneg
,fabs
, orfcopysing
is a NaN, then its sign is non-deterministic and the payload is computed as follows:
- If the payload of all NaN inputs to the operator is canonical (including the case that there are no NaN inputs), then the payload of the output is canonical as well.
- Otherwise the payload is picked non-deterministically among all arithmetic NaNs; that is, its most significant bit is 1 and all others are unspecified.
In the original test case the part that makes the test fail is that RISC-V flips the sign of the NaN on promotion. I think this is allowed since the spec states
its sign is non-deterministic
. I think clearing the payload bits is also allowed, although it doesn't really matter here.So, am I reading the above correctly? And if so should we just leave this test disabled for RISC-V, or try to rewrite it in a conformant way?
afonso360 added the bug label to Issue #6961.
afonso360 added the cranelift:area:riscv64 label to Issue #6961.
alexcrichton commented on issue #6961:
I believe you're correct in your conclusion here. I'll also link the documented semantics for promotion which explicitly agree with the NaN propagation section.
Given this I'd say it's ok to ignore the test on RISC-V. Ideally the test could be rewritten to accomodate platform differences but that seems difficult here as this is stressing a specific codegen bug. There's various s-expression matchers for "any nan" or "any arithmetic nan" which I think is ideally what's wanted here.
alexcrichton closed issue #6961:
:wave: Hey,
This is the last remaining SIMD test that is disabled for RISC-V. I'm fairly sure that the RISC-V backend implements a spec compliant implementation of these instructions but I'd like to confirm it.
Test Case
The original test is the following:
;; from #3327 (module (func (result i32) v128.const i32x4 0xffffffff 0x80bfffff 0x80bf0a0a 0x80bf0a0a f64x2.promote_low_f32x4 v128.not v128.not v128.not v128.not v128.not v128.not v128.not v128.const i32x4 0 0 0 0 f64x2.gt v128.not i64x2.bitmask) (export "" (func 0))) (assert_return (invoke "") (i32.const 0))
Steps to Reproduce
cargo run --target=riscv64gc-unknown-linux-gnu -- wast --disable-cache ./tests/misc_testsuite/simd/issue_3327_bnot_lowering.wast
Expected Results
The test to pass
Actual Results
RISC-V fails.
Versions and Environment
Wasmtime version or commit: main
Operating system: Linux
Architecture: RISC-V
Extra Info
I've reduced the above input down to following clif test:
test interpret test run target riscv64gc has_v target x86_64 function %a(i64) -> f64 fast { const0 = 0x80bf0a0a80bf0a0a80bfffffffffffff block0(v1: i64): v3 = vconst.f32x4 const0 v5 = fvpromote_low v3 v6 = extractlane v5, 0 return v6 } ;; X86_64 passes this ; run: %a(0) == -NaN:0x7ffffe0000000 ;; RISCV64 passes this ; run: %a(0) == NaN
RISC-V returns a Positive Canonical NaN from
fvpromote_low
. While X86 keeps the NaN as negative (and preserves payload bits). In the original test case the NaNs are then compared to check if they are negative, this passes on x86, but not on RISC-V.The docs on
fvpromote_low
don't specify what the correct behaviour here is. So I've looked at the NaN Propagation section of the WASM specification where it states:When the result of a floating-point operator other than
fneg
,fabs
, orfcopysing
is a NaN, then its sign is non-deterministic and the payload is computed as follows:
- If the payload of all NaN inputs to the operator is canonical (including the case that there are no NaN inputs), then the payload of the output is canonical as well.
- Otherwise the payload is picked non-deterministically among all arithmetic NaNs; that is, its most significant bit is 1 and all others are unspecified.
In the original test case the part that makes the test fail is that RISC-V flips the sign of the NaN on promotion. I think this is allowed since the spec states
its sign is non-deterministic
. I think clearing the payload bits is also allowed, although it doesn't really matter here.So, am I reading the above correctly? And if so should we just leave this test disabled for RISC-V, or try to rewrite it in a conformant way?
Last updated: Dec 23 2024 at 12:05 UTC