amd64: correctly select sign of zeros on f32x4/f64x2 min/max (#730)

This commit is contained in:
Takeshi Yoneda
2022-08-02 19:47:49 +09:00
committed by GitHub
parent b02b5513e8
commit 9dfdab2548
6 changed files with 250 additions and 93 deletions

View File

@@ -265,3 +265,36 @@ func Test725(t *testing.T) {
}
})
}
// Test730 ensures that the vector min/max operations comply with the spec wrt sign bits of zeros:
//
// - min(0, 0) = 0, min(-0, 0) = -0, min(0, -0) = -0, min(-0, -0) = -0
// - max(0, 0) = 0, max(-0, 0) = 0, max(0, -0) = 0, max(-0, -0) = -0
func Test730(t *testing.T) {
tests := []struct {
name string
exp [2]uint64
}{
{name: "f32x4.max", exp: [2]uint64{0x80000000 << 32, 0x00000000}},
{name: "f32x4.min", exp: [2]uint64{0x80000000, 0x80000000<<32 | 0x80000000}},
{name: "f64x2.max", exp: [2]uint64{0, 0}},
{name: "f64x2.min", exp: [2]uint64{1 << 63, 1 << 63}},
{name: "f64x2.max/mix", exp: [2]uint64{0, 1 << 63}},
{name: "f64x2.min/mix", exp: [2]uint64{1 << 63, 0}},
}
run(t, func(t *testing.T, r wazero.Runtime) {
mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 730))
require.NoError(t, err)
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
f := mod.ExportedFunction(tc.name)
require.NotNil(t, f)
actual, err := f.Call(ctx)
require.NoError(t, err)
require.Equal(t, tc.exp[:], actual)
})
}
})
}

Binary file not shown.

View File

@@ -0,0 +1,32 @@
(module
(func (export "f32x4.max") (result v128)
v128.const i32x4 0x80000000 0x80000000 0x00000000 0x00000000 ;; (-0 -0, 0, 0)
v128.const i32x4 0x00000000 0x80000000 0x80000000 0x80000000 ;; (0, -0, 0, -0)
f32x4.max ;; (0, -0, 0, 0)
)
(func (export "f32x4.min") (result v128)
v128.const i32x4 0x80000000 0x00000000 0x00000000 0x00000000 ;; (-0 -0, 0, 0)
v128.const i32x4 0x00000000 0x00000000 0x80000000 0x80000000 ;; (0, -0, 0, -0)
f32x4.min ;; (-0, 0, -0, -0)
)
(func (export "f64x2.max") (result v128)
v128.const i64x2 0x8000000000000000 0x0000000000000000 ;; (-0 0)
v128.const i64x2 0x0000000000000000 0x8000000000000000 ;; (0, -0)
f64x2.max ;; (0, 0)
)
(func (export "f64x2.min") (result v128)
v128.const i64x2 0x8000000000000000 0x0000000000000000 ;; (-0 0)
v128.const i64x2 0x0000000000000000 0x8000000000000000 ;; (0, -0)
f64x2.min ;; (-0, -0)
)
(func (export "f64x2.max/mix") (result v128)
v128.const i64x2 0x8000000000000000 0x8000000000000000 ;; (-0, -0)
v128.const i64x2 0x0000000000000000 0x8000000000000000 ;; (0, -0)
f64x2.max ;; (0, -0)
)
(func (export "f64x2.min/mix") (result v128)
v128.const i64x2 0x8000000000000000 0x0000000000000000 ;; (-0, 0)
v128.const i64x2 0x0000000000000000 0x0000000000000000 ;; (0, 0)
f64x2.min ;; (-0, 0)
)
)