From 110aaf7137430595faaee5623ab724d73c1f9aab Mon Sep 17 00:00:00 2001 From: Cherry Mui Date: Mon, 29 Dec 2025 14:56:53 -0500 Subject: [PATCH] simd/archsimd: add tests for Saturate operations Change-Id: Iea095112310802b29b4ef9ca6e559ea3c5aa83ed Reviewed-on: https://go-review.googlesource.com/c/go/+/733140 LUCI-TryBot-Result: Go LUCI Reviewed-by: David Chase --- .../simd_test/simulation_helpers_test.go | 87 +++++++++++++++++++ .../archsimd/internal/simd_test/unary_test.go | 42 +++++++++ 2 files changed, 129 insertions(+) diff --git a/src/simd/archsimd/internal/simd_test/simulation_helpers_test.go b/src/simd/archsimd/internal/simd_test/simulation_helpers_test.go index a51912a47f..da107d8061 100644 --- a/src/simd/archsimd/internal/simd_test/simulation_helpers_test.go +++ b/src/simd/archsimd/internal/simd_test/simulation_helpers_test.go @@ -330,3 +330,90 @@ func imaSlice[T integer](x, y, z []T) []T { func fmaSlice[T float](x, y, z []T) []T { return map3[T](fma)(x, y, z) } + +func satToInt8[T integer](x T) int8 { + var m int8 = -128 + var M int8 = 127 + if T(M) < T(m) { // expecting T being a larger type + panic("bad input type") + } + if x < T(m) { + return m + } + if x > T(M) { + return M + } + return int8(x) +} + +func satToUint8[T integer](x T) uint8 { + var M uint8 = 255 + if T(M) < 0 { // expecting T being a larger type + panic("bad input type") + } + if x < 0 { + return 0 + } + if x > T(M) { + return M + } + return uint8(x) +} + +func satToInt16[T integer](x T) int16 { + var m int16 = -32768 + var M int16 = 32767 + if T(M) < T(m) { // expecting T being a larger type + panic("bad input type") + } + if x < T(m) { + return m + } + if x > T(M) { + return M + } + return int16(x) +} + +func satToUint16[T integer](x T) uint16 { + var M uint16 = 65535 + if T(M) < 0 { // expecting T being a larger type + panic("bad input type") + } + if x < 0 { + return 0 + } + if x > T(M) { + return M + } + return uint16(x) +} + +func satToInt32[T integer](x T) int32 { + var m int32 = -1 << 31 + var M int32 = 1<<31 - 1 + if T(M) < T(m) { // expecting T being a larger type + panic("bad input type") + } + if x < T(m) { + return m + } + if x > T(M) { + return M + } + return int32(x) +} + +func satToUint32[T integer](x T) uint32 { + var M uint32 = 1<<32 - 1 + if T(M) < 0 { // expecting T being a larger type + panic("bad input type") + } + if x < 0 { + return 0 + } + if x > T(M) { + return M + } + return uint32(x) +} diff --git a/src/simd/archsimd/internal/simd_test/unary_test.go b/src/simd/archsimd/internal/simd_test/unary_test.go index 5d00eba03d..097feb60ed 100644 --- a/src/simd/archsimd/internal/simd_test/unary_test.go +++ b/src/simd/archsimd/internal/simd_test/unary_test.go @@ -270,3 +270,45 @@ func TestTruncate(t *testing.T) { testUint64x8ConvertToUint32(t, archsimd.Uint64x8.TruncateToUint32, map1[uint64](toUint32)) } } + +func TestSaturate(t *testing.T) { + if archsimd.X86.AVX512() { + testInt16x8ConvertToInt8(t, archsimd.Int16x8.SaturateToInt8, map1n[int16](satToInt8, 16)) + testInt16x16ConvertToInt8(t, archsimd.Int16x16.SaturateToInt8, map1[int16](satToInt8)) + testInt16x32ConvertToInt8(t, archsimd.Int16x32.SaturateToInt8, map1[int16](satToInt8)) + testInt32x4ConvertToInt8(t, archsimd.Int32x4.SaturateToInt8, map1n[int32](satToInt8, 16)) + testInt32x8ConvertToInt8(t, archsimd.Int32x8.SaturateToInt8, map1n[int32](satToInt8, 16)) + testInt32x16ConvertToInt8(t, archsimd.Int32x16.SaturateToInt8, map1[int32](satToInt8)) + testInt64x2ConvertToInt8(t, archsimd.Int64x2.SaturateToInt8, map1n[int64](satToInt8, 16)) + testInt64x4ConvertToInt8(t, archsimd.Int64x4.SaturateToInt8, map1n[int64](satToInt8, 16)) + testInt64x8ConvertToInt8(t, archsimd.Int64x8.SaturateToInt8, map1n[int64](satToInt8, 16)) + testInt32x4ConvertToInt16(t, archsimd.Int32x4.SaturateToInt16, map1n[int32](satToInt16, 8)) + testInt32x8ConvertToInt16(t, archsimd.Int32x8.SaturateToInt16, map1[int32](satToInt16)) + testInt32x16ConvertToInt16(t, archsimd.Int32x16.SaturateToInt16, map1[int32](satToInt16)) + testInt64x2ConvertToInt16(t, archsimd.Int64x2.SaturateToInt16, map1n[int64](satToInt16, 8)) + testInt64x4ConvertToInt16(t, archsimd.Int64x4.SaturateToInt16, map1n[int64](satToInt16, 8)) + testInt64x8ConvertToInt16(t, archsimd.Int64x8.SaturateToInt16, map1[int64](satToInt16)) + testInt64x2ConvertToInt32(t, archsimd.Int64x2.SaturateToInt32, map1n[int64](satToInt32, 4)) + testInt64x4ConvertToInt32(t, archsimd.Int64x4.SaturateToInt32, map1[int64](satToInt32)) + testInt64x8ConvertToInt32(t, archsimd.Int64x8.SaturateToInt32, map1[int64](satToInt32)) + + testUint16x8ConvertToUint8(t, archsimd.Uint16x8.SaturateToUint8, map1n[uint16](satToUint8, 16)) + testUint16x16ConvertToUint8(t, archsimd.Uint16x16.SaturateToUint8, map1[uint16](satToUint8)) + testUint16x32ConvertToUint8(t, archsimd.Uint16x32.SaturateToUint8, map1[uint16](satToUint8)) + testUint32x4ConvertToUint8(t, archsimd.Uint32x4.SaturateToUint8, map1n[uint32](satToUint8, 16)) + testUint32x8ConvertToUint8(t, archsimd.Uint32x8.SaturateToUint8, map1n[uint32](satToUint8, 16)) + testUint32x16ConvertToUint8(t, archsimd.Uint32x16.SaturateToUint8, map1[uint32](satToUint8)) + testUint64x2ConvertToUint8(t, archsimd.Uint64x2.SaturateToUint8, map1n[uint64](satToUint8, 16)) + testUint64x4ConvertToUint8(t, archsimd.Uint64x4.SaturateToUint8, map1n[uint64](satToUint8, 16)) + testUint64x8ConvertToUint8(t, archsimd.Uint64x8.SaturateToUint8, map1n[uint64](satToUint8, 16)) + testUint32x4ConvertToUint16(t, archsimd.Uint32x4.SaturateToUint16, map1n[uint32](satToUint16, 8)) + testUint32x8ConvertToUint16(t, archsimd.Uint32x8.SaturateToUint16, map1[uint32](satToUint16)) + testUint32x16ConvertToUint16(t, archsimd.Uint32x16.SaturateToUint16, map1[uint32](satToUint16)) + testUint64x2ConvertToUint16(t, archsimd.Uint64x2.SaturateToUint16, map1n[uint64](satToUint16, 8)) + testUint64x4ConvertToUint16(t, archsimd.Uint64x4.SaturateToUint16, map1n[uint64](satToUint16, 8)) + testUint64x8ConvertToUint16(t, archsimd.Uint64x8.SaturateToUint16, map1[uint64](satToUint16)) + testUint64x2ConvertToUint32(t, archsimd.Uint64x2.SaturateToUint32, map1n[uint64](satToUint32, 4)) + testUint64x4ConvertToUint32(t, archsimd.Uint64x4.SaturateToUint32, map1[uint64](satToUint32)) + testUint64x8ConvertToUint32(t, archsimd.Uint64x8.SaturateToUint32, map1[uint64](satToUint32)) + } +} -- 2.52.0