diff options
author | Brendan Dahl <brendan.dahl@gmail.com> | 2024-09-06 15:37:39 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-06 15:37:39 -0700 |
commit | 4d58e2770b121e319025196c0cc2622864c47098 (patch) | |
tree | f162c96e1063742cfd154734e87023595164dea2 | |
parent | 655eab84019236d02032ceb61570f4f34ee8ac0d (diff) | |
download | binaryen-4d58e2770b121e319025196c0cc2622864c47098.tar.gz binaryen-4d58e2770b121e319025196c0cc2622864c47098.tar.bz2 binaryen-4d58e2770b121e319025196c0cc2622864c47098.zip |
[FP16] Fix replace lane for F16x8. (#6906)
Before this change, replace lane was converting all the F16 lanes to F32
and then replacing one lane with the F16 (I32 representation) value, but
it did not then convert all the other lanes back to F16 (I32). To fix
this we can just leave the lanes as I32 and replace the one lane.
Note: Previous replace lane tests didn't catch this since they started
with vectors with all zeros so the F32->I32 didn't matter. Also, other
operations don't run into this issue since they iterate over all lanes
and convert the F32's back to F16 (I32).
---------
Co-authored-by: Alon Zakai <alonzakai@gmail.com>
-rw-r--r-- | src/wasm/literal.cpp | 5 | ||||
-rw-r--r-- | test/spec/f16.wast | 7 |
2 files changed, 11 insertions, 1 deletions
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index e332db305..e8641cbd7 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -1834,7 +1834,10 @@ Literal Literal::replaceLaneI64x2(const Literal& other, uint8_t index) const { return replace<2, &Literal::getLanesI64x2>(*this, other, index); } Literal Literal::replaceLaneF16x8(const Literal& other, uint8_t index) const { - return replace<8, &Literal::getLanesF16x8>( + // For F16 lane replacement we do not need to convert all the values to F32, + // instead keep the lanes as I32, and just replace the one lane with the + // integer value of the F32. + return replace<8, &Literal::getLanesUI16x8>( *this, other.convertF32ToF16(), index); } Literal Literal::replaceLaneF32x4(const Literal& other, uint8_t index) const { diff --git a/test/spec/f16.wast b/test/spec/f16.wast index d5de0c0e8..f0d2b0678 100644 --- a/test/spec/f16.wast +++ b/test/spec/f16.wast @@ -34,6 +34,9 @@ (func (export "f16x8.nearest") (param $0 v128) (result v128) (f16x8.nearest (local.get $0))) (func (export "f16x8.relaxed_madd") (param $0 v128) (param $1 v128) (param $2 v128) (result v128) (f16x8.relaxed_madd (local.get $0) (local.get $1) (local.get $2))) (func (export "f16x8.relaxed_nmadd") (param $0 v128) (param $1 v128) (param $2 v128) (result v128) (f16x8.relaxed_nmadd (local.get $0) (local.get $1) (local.get $2))) + ;; Multiple operation tests: + (func (export "splat_replace") (result v128) (f16x8.replace_lane 0 (f16x8.splat (f32.const 1)) (f32.const 99)) + ) ) (assert_return (invoke "f32.load_f16") (f32.const 42.0)) @@ -216,3 +219,7 @@ (v128.const i16x8 0x7c00 0x7c00 0xbc00 0 0x3c00 0x4000 0x3c00 0xbc00)) ;; inf inf -2 0 0 -0.25 9 -2 (v128.const i16x8 0x7c00 0x7c00 0xc000 0 0 0xb400 0x4880 0xc000)) + +(assert_return (invoke "splat_replace") + (v128.const i16x8 0x5630 0x3c00 0x3c00 0x3c00 0x3c00 0x3c00 0x3c00 0x3c00) +) |