mirror of
https://github.com/golang/go.git
synced 2026-01-29 15:12:08 +03:00
simd/archsimd: add more tests for Convert operations
For now, only include operations that input and output vectors have the same number of elements. Change-Id: If4722f1b0168eaf0e333bdcd218e394fa4ab440f Reviewed-on: https://go-review.googlesource.com/c/go/+/732662 Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
@@ -121,16 +121,6 @@ func toUint64[T number](x T) uint64 {
|
||||
}
|
||||
|
||||
func toUint32[T number](x T) uint32 {
|
||||
switch y := (any(x)).(type) {
|
||||
case float32:
|
||||
if y < 0 || y > float32(math.MaxUint32) || y != y {
|
||||
return math.MaxUint32
|
||||
}
|
||||
case float64:
|
||||
if y < 0 || y > float64(math.MaxUint32) || y != y {
|
||||
return math.MaxUint32
|
||||
}
|
||||
}
|
||||
return uint32(x)
|
||||
}
|
||||
|
||||
@@ -158,6 +148,74 @@ func toFloat64[T number](x T) float64 {
|
||||
return float64(x)
|
||||
}
|
||||
|
||||
// X86 specific behavior for conversion from float to int32.
|
||||
// If the value cannot be represented as int32, it returns -0x80000000.
|
||||
func floatToInt32_x86[T float](x T) int32 {
|
||||
switch y := (any(x)).(type) {
|
||||
case float32:
|
||||
if y != y || y < math.MinInt32 ||
|
||||
y >= math.MaxInt32 { // float32(MaxInt32) == 0x80000000, actually overflows
|
||||
return -0x80000000
|
||||
}
|
||||
case float64:
|
||||
if y != y || y < math.MinInt32 ||
|
||||
y > math.MaxInt32 { // float64(MaxInt32) is exact, no overflow
|
||||
return -0x80000000
|
||||
}
|
||||
}
|
||||
return int32(x)
|
||||
}
|
||||
|
||||
// X86 specific behavior for conversion from float to int64.
|
||||
// If the value cannot be represented as int64, it returns -0x80000000_00000000.
|
||||
func floatToInt64_x86[T float](x T) int64 {
|
||||
switch y := (any(x)).(type) {
|
||||
case float32:
|
||||
if y != y || y < math.MinInt64 ||
|
||||
y >= math.MaxInt64 { // float32(MaxInt64) == 0x80000000_00000000, actually overflows
|
||||
return -0x80000000_00000000
|
||||
}
|
||||
case float64:
|
||||
if y != y || y < math.MinInt64 ||
|
||||
y >= math.MaxInt64 { // float64(MaxInt64) == 0x80000000_00000000, also overflows
|
||||
return -0x80000000_00000000
|
||||
}
|
||||
}
|
||||
return int64(x)
|
||||
}
|
||||
|
||||
// X86 specific behavior for conversion from float to uint32.
|
||||
// If the value cannot be represented as uint32, it returns 1<<32 - 1.
|
||||
func floatToUint32_x86[T float](x T) uint32 {
|
||||
switch y := (any(x)).(type) {
|
||||
case float32:
|
||||
if y < 0 || y > math.MaxUint32 || y != y {
|
||||
return 1<<32 - 1
|
||||
}
|
||||
case float64:
|
||||
if y < 0 || y > math.MaxUint32 || y != y {
|
||||
return 1<<32 - 1
|
||||
}
|
||||
}
|
||||
return uint32(x)
|
||||
}
|
||||
|
||||
// X86 specific behavior for conversion from float to uint64.
|
||||
// If the value cannot be represented as uint64, it returns 1<<64 - 1.
|
||||
func floatToUint64_x86[T float](x T) uint64 {
|
||||
switch y := (any(x)).(type) {
|
||||
case float32:
|
||||
if y < 0 || y > math.MaxUint64 || y != y {
|
||||
return 1<<64 - 1
|
||||
}
|
||||
case float64:
|
||||
if y < 0 || y > math.MaxUint64 || y != y {
|
||||
return 1<<64 - 1
|
||||
}
|
||||
}
|
||||
return uint64(x)
|
||||
}
|
||||
|
||||
func ceilResidueForPrecision[T float](i int) func(T) T {
|
||||
f := 1.0
|
||||
for i > 0 {
|
||||
|
||||
@@ -116,18 +116,59 @@ func TestCeilScaledResidue(t *testing.T) {
|
||||
map1[float64](func(x float64) float64 { return x - math.Ceil(x) }))
|
||||
}
|
||||
|
||||
func TestToUint32(t *testing.T) {
|
||||
if !archsimd.X86.AVX512() {
|
||||
t.Skip("Needs AVX512")
|
||||
}
|
||||
testFloat32x4ConvertToUint32(t, archsimd.Float32x4.ConvertToUint32, map1[float32](toUint32))
|
||||
testFloat32x8ConvertToUint32(t, archsimd.Float32x8.ConvertToUint32, map1[float32](toUint32))
|
||||
testFloat32x16ConvertToUint32(t, archsimd.Float32x16.ConvertToUint32, map1[float32](toUint32))
|
||||
}
|
||||
func TestConvert(t *testing.T) {
|
||||
testFloat32x4ConvertToFloat64(t, archsimd.Float32x4.ConvertToFloat64, map1[float32](toFloat64))
|
||||
testFloat64x4ConvertToFloat32(t, archsimd.Float64x4.ConvertToFloat32, map1[float64](toFloat32))
|
||||
|
||||
func TestToInt32(t *testing.T) {
|
||||
testFloat32x4ConvertToInt32(t, archsimd.Float32x4.ConvertToInt32, map1[float32](toInt32))
|
||||
testFloat32x8ConvertToInt32(t, archsimd.Float32x8.ConvertToInt32, map1[float32](toInt32))
|
||||
testFloat32x4ConvertToInt32(t, archsimd.Float32x4.ConvertToInt32, map1[float32](floatToInt32_x86))
|
||||
testFloat32x8ConvertToInt32(t, archsimd.Float32x8.ConvertToInt32, map1[float32](floatToInt32_x86))
|
||||
testFloat64x4ConvertToInt32(t, archsimd.Float64x4.ConvertToInt32, map1[float64](floatToInt32_x86))
|
||||
|
||||
testInt32x4ConvertToFloat32(t, archsimd.Int32x4.ConvertToFloat32, map1[int32](toFloat32))
|
||||
testInt32x4ConvertToFloat64(t, archsimd.Int32x4.ConvertToFloat64, map1[int32](toFloat64))
|
||||
testInt32x8ConvertToFloat32(t, archsimd.Int32x8.ConvertToFloat32, map1[int32](toFloat32))
|
||||
|
||||
if archsimd.X86.AVX512() {
|
||||
testFloat32x8ConvertToFloat64(t, archsimd.Float32x8.ConvertToFloat64, map1[float32](toFloat64))
|
||||
testFloat64x8ConvertToFloat32(t, archsimd.Float64x8.ConvertToFloat32, map1[float64](toFloat32))
|
||||
|
||||
testFloat32x16ConvertToInt32(t, archsimd.Float32x16.ConvertToInt32, map1[float32](floatToInt32_x86))
|
||||
testFloat64x8ConvertToInt32(t, archsimd.Float64x8.ConvertToInt32, map1[float64](floatToInt32_x86))
|
||||
testFloat32x4ConvertToInt64(t, archsimd.Float32x4.ConvertToInt64, map1[float32](floatToInt64_x86))
|
||||
testFloat32x8ConvertToInt64(t, archsimd.Float32x8.ConvertToInt64, map1[float32](floatToInt64_x86))
|
||||
testFloat64x2ConvertToInt64(t, archsimd.Float64x2.ConvertToInt64, map1[float64](floatToInt64_x86))
|
||||
testFloat64x4ConvertToInt64(t, archsimd.Float64x4.ConvertToInt64, map1[float64](floatToInt64_x86))
|
||||
testFloat64x8ConvertToInt64(t, archsimd.Float64x8.ConvertToInt64, map1[float64](floatToInt64_x86))
|
||||
|
||||
testFloat32x4ConvertToUint32(t, archsimd.Float32x4.ConvertToUint32, map1[float32](floatToUint32_x86))
|
||||
testFloat32x8ConvertToUint32(t, archsimd.Float32x8.ConvertToUint32, map1[float32](floatToUint32_x86))
|
||||
testFloat32x16ConvertToUint32(t, archsimd.Float32x16.ConvertToUint32, map1[float32](floatToUint32_x86))
|
||||
testFloat64x4ConvertToUint32(t, archsimd.Float64x4.ConvertToUint32, map1[float64](floatToUint32_x86))
|
||||
testFloat64x8ConvertToUint32(t, archsimd.Float64x8.ConvertToUint32, map1[float64](floatToUint32_x86))
|
||||
testFloat32x4ConvertToUint64(t, archsimd.Float32x4.ConvertToUint64, map1[float32](floatToUint64_x86))
|
||||
testFloat32x8ConvertToUint64(t, archsimd.Float32x8.ConvertToUint64, map1[float32](floatToUint64_x86))
|
||||
testFloat64x2ConvertToUint64(t, archsimd.Float64x2.ConvertToUint64, map1[float64](floatToUint64_x86))
|
||||
testFloat64x4ConvertToUint64(t, archsimd.Float64x4.ConvertToUint64, map1[float64](floatToUint64_x86))
|
||||
testFloat64x8ConvertToUint64(t, archsimd.Float64x8.ConvertToUint64, map1[float64](floatToUint64_x86))
|
||||
|
||||
testInt32x16ConvertToFloat32(t, archsimd.Int32x16.ConvertToFloat32, map1[int32](toFloat32))
|
||||
testInt64x4ConvertToFloat32(t, archsimd.Int64x4.ConvertToFloat32, map1[int64](toFloat32))
|
||||
testInt64x8ConvertToFloat32(t, archsimd.Int64x8.ConvertToFloat32, map1[int64](toFloat32))
|
||||
testInt64x2ConvertToFloat64(t, archsimd.Int64x2.ConvertToFloat64, map1[int64](toFloat64))
|
||||
testInt64x4ConvertToFloat64(t, archsimd.Int64x4.ConvertToFloat64, map1[int64](toFloat64))
|
||||
testInt64x8ConvertToFloat64(t, archsimd.Int64x8.ConvertToFloat64, map1[int64](toFloat64))
|
||||
|
||||
testUint32x4ConvertToFloat32(t, archsimd.Uint32x4.ConvertToFloat32, map1[uint32](toFloat32))
|
||||
testUint32x8ConvertToFloat32(t, archsimd.Uint32x8.ConvertToFloat32, map1[uint32](toFloat32))
|
||||
testUint32x16ConvertToFloat32(t, archsimd.Uint32x16.ConvertToFloat32, map1[uint32](toFloat32))
|
||||
testUint64x4ConvertToFloat32(t, archsimd.Uint64x4.ConvertToFloat32, map1[uint64](toFloat32))
|
||||
testUint64x8ConvertToFloat32(t, archsimd.Uint64x8.ConvertToFloat32, map1[uint64](toFloat32))
|
||||
testUint32x4ConvertToFloat64(t, archsimd.Uint32x4.ConvertToFloat64, map1[uint32](toFloat64))
|
||||
testUint32x8ConvertToFloat64(t, archsimd.Uint32x8.ConvertToFloat64, map1[uint32](toFloat64))
|
||||
testUint64x2ConvertToFloat64(t, archsimd.Uint64x2.ConvertToFloat64, map1[uint64](toFloat64))
|
||||
testUint64x4ConvertToFloat64(t, archsimd.Uint64x4.ConvertToFloat64, map1[uint64](toFloat64))
|
||||
testUint64x8ConvertToFloat64(t, archsimd.Uint64x8.ConvertToFloat64, map1[uint64](toFloat64))
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtend(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user