From 934dbcea1a806c198a7870b1808fb8e41b568984 Mon Sep 17 00:00:00 2001 From: Junyang Shao Date: Wed, 12 Nov 2025 19:56:09 +0000 Subject: [PATCH] [dev.simd] simd: update CPU feature APIs This CL also updates the internal uses of these APIs. This CL also fixed a instable output issue left by previous CLs. Change-Id: Ibc38361d35e2af0c4943a48578f3c610b74ed14d Reviewed-on: https://go-review.googlesource.com/c/go/+/720020 Reviewed-by: Cherry Mui LUCI-TryBot-Result: Go LUCI --- src/simd/_gen/simdgen/gen_simdTypes.go | 12 ++- src/simd/cpu.go | 82 ++++++++++--------- src/simd/internal/simd_test/binary_test.go | 28 +++---- src/simd/internal/simd_test/compare_test.go | 14 ++-- src/simd/internal/simd_test/simd_test.go | 78 +++++++++--------- src/simd/internal/simd_test/slicepart_test.go | 4 +- src/simd/internal/simd_test/ternary_test.go | 2 +- src/simd/internal/simd_test/unary_test.go | 18 ++-- src/simd/pkginternal_test.go | 2 +- test/codegen/simd.go | 4 +- test/simd.go | 16 ++-- 11 files changed, 134 insertions(+), 126 deletions(-) diff --git a/src/simd/_gen/simdgen/gen_simdTypes.go b/src/simd/_gen/simdgen/gen_simdTypes.go index c809fcd1dee..b33c51b1aba 100644 --- a/src/simd/_gen/simdgen/gen_simdTypes.go +++ b/src/simd/_gen/simdgen/gen_simdTypes.go @@ -146,21 +146,25 @@ type {{.Name}} struct { const simdFeaturesTemplate = ` import "internal/cpu" +type X86Features struct {} + +var X86 X86Features + {{range .}} {{- if eq .Feature "AVX512"}} -// Has{{.Feature}} returns whether the CPU supports the AVX512F+CD+BW+DQ+VL features. +// {{.Feature}} returns whether the CPU supports the AVX512F+CD+BW+DQ+VL features. // // These five CPU features are bundled together, and no use of AVX-512 // is allowed unless all of these features are supported together. // Nearly every CPU that has shipped with any support for AVX-512 has // supported all five of these features. {{- else -}} -// Has{{.Feature}} returns whether the CPU supports the {{.Feature}} feature. +// {{.Feature}} returns whether the CPU supports the {{.Feature}} feature. {{- end}} // -// Has{{.Feature}} is defined on all GOARCHes, but will only return true on +// {{.Feature}} is defined on all GOARCHes, but will only return true on // GOARCH {{.GoArch}}. -func Has{{.Feature}}() bool { +func (X86Features) {{.Feature}}() bool { return cpu.X86.Has{{.Feature}} } {{end}} diff --git a/src/simd/cpu.go b/src/simd/cpu.go index ca445072c03..7c348baedcc 100644 --- a/src/simd/cpu.go +++ b/src/simd/cpu.go @@ -6,111 +6,115 @@ package simd import "internal/cpu" -// HasAES returns whether the CPU supports the AES feature. +type X86Features struct{} + +var X86 X86Features + +// AES returns whether the CPU supports the AES feature. // -// HasAES is defined on all GOARCHes, but will only return true on +// AES is defined on all GOARCHes, but will only return true on // GOARCH amd64. -func HasAES() bool { +func (X86Features) AES() bool { return cpu.X86.HasAES } -// HasAVX returns whether the CPU supports the AVX feature. +// AVX returns whether the CPU supports the AVX feature. // -// HasAVX is defined on all GOARCHes, but will only return true on +// AVX is defined on all GOARCHes, but will only return true on // GOARCH amd64. -func HasAVX() bool { +func (X86Features) AVX() bool { return cpu.X86.HasAVX } -// HasAVX2 returns whether the CPU supports the AVX2 feature. +// AVX2 returns whether the CPU supports the AVX2 feature. // -// HasAVX2 is defined on all GOARCHes, but will only return true on +// AVX2 is defined on all GOARCHes, but will only return true on // GOARCH amd64. -func HasAVX2() bool { +func (X86Features) AVX2() bool { return cpu.X86.HasAVX2 } -// HasAVX512 returns whether the CPU supports the AVX512F+CD+BW+DQ+VL features. +// AVX512 returns whether the CPU supports the AVX512F+CD+BW+DQ+VL features. // // These five CPU features are bundled together, and no use of AVX-512 // is allowed unless all of these features are supported together. // Nearly every CPU that has shipped with any support for AVX-512 has // supported all five of these features. // -// HasAVX512 is defined on all GOARCHes, but will only return true on +// AVX512 is defined on all GOARCHes, but will only return true on // GOARCH amd64. -func HasAVX512() bool { +func (X86Features) AVX512() bool { return cpu.X86.HasAVX512 } -// HasAVX512BITALG returns whether the CPU supports the AVX512BITALG feature. +// AVX512BITALG returns whether the CPU supports the AVX512BITALG feature. // -// HasAVX512BITALG is defined on all GOARCHes, but will only return true on +// AVX512BITALG is defined on all GOARCHes, but will only return true on // GOARCH amd64. -func HasAVX512BITALG() bool { +func (X86Features) AVX512BITALG() bool { return cpu.X86.HasAVX512BITALG } -// HasAVX512GFNI returns whether the CPU supports the AVX512GFNI feature. +// AVX512GFNI returns whether the CPU supports the AVX512GFNI feature. // -// HasAVX512GFNI is defined on all GOARCHes, but will only return true on +// AVX512GFNI is defined on all GOARCHes, but will only return true on // GOARCH amd64. -func HasAVX512GFNI() bool { +func (X86Features) AVX512GFNI() bool { return cpu.X86.HasAVX512GFNI } -// HasAVX512VAES returns whether the CPU supports the AVX512VAES feature. +// AVX512VAES returns whether the CPU supports the AVX512VAES feature. // -// HasAVX512VAES is defined on all GOARCHes, but will only return true on +// AVX512VAES is defined on all GOARCHes, but will only return true on // GOARCH amd64. -func HasAVX512VAES() bool { +func (X86Features) AVX512VAES() bool { return cpu.X86.HasAVX512VAES } -// HasAVX512VBMI returns whether the CPU supports the AVX512VBMI feature. +// AVX512VBMI returns whether the CPU supports the AVX512VBMI feature. // -// HasAVX512VBMI is defined on all GOARCHes, but will only return true on +// AVX512VBMI is defined on all GOARCHes, but will only return true on // GOARCH amd64. -func HasAVX512VBMI() bool { +func (X86Features) AVX512VBMI() bool { return cpu.X86.HasAVX512VBMI } -// HasAVX512VBMI2 returns whether the CPU supports the AVX512VBMI2 feature. +// AVX512VBMI2 returns whether the CPU supports the AVX512VBMI2 feature. // -// HasAVX512VBMI2 is defined on all GOARCHes, but will only return true on +// AVX512VBMI2 is defined on all GOARCHes, but will only return true on // GOARCH amd64. -func HasAVX512VBMI2() bool { +func (X86Features) AVX512VBMI2() bool { return cpu.X86.HasAVX512VBMI2 } -// HasAVX512VNNI returns whether the CPU supports the AVX512VNNI feature. +// AVX512VNNI returns whether the CPU supports the AVX512VNNI feature. // -// HasAVX512VNNI is defined on all GOARCHes, but will only return true on +// AVX512VNNI is defined on all GOARCHes, but will only return true on // GOARCH amd64. -func HasAVX512VNNI() bool { +func (X86Features) AVX512VNNI() bool { return cpu.X86.HasAVX512VNNI } -// HasAVX512VPOPCNTDQ returns whether the CPU supports the AVX512VPOPCNTDQ feature. +// AVX512VPOPCNTDQ returns whether the CPU supports the AVX512VPOPCNTDQ feature. // -// HasAVX512VPOPCNTDQ is defined on all GOARCHes, but will only return true on +// AVX512VPOPCNTDQ is defined on all GOARCHes, but will only return true on // GOARCH amd64. -func HasAVX512VPOPCNTDQ() bool { +func (X86Features) AVX512VPOPCNTDQ() bool { return cpu.X86.HasAVX512VPOPCNTDQ } -// HasAVXVNNI returns whether the CPU supports the AVXVNNI feature. +// AVXVNNI returns whether the CPU supports the AVXVNNI feature. // -// HasAVXVNNI is defined on all GOARCHes, but will only return true on +// AVXVNNI is defined on all GOARCHes, but will only return true on // GOARCH amd64. -func HasAVXVNNI() bool { +func (X86Features) AVXVNNI() bool { return cpu.X86.HasAVXVNNI } -// HasSHA returns whether the CPU supports the SHA feature. +// SHA returns whether the CPU supports the SHA feature. // -// HasSHA is defined on all GOARCHes, but will only return true on +// SHA is defined on all GOARCHes, but will only return true on // GOARCH amd64. -func HasSHA() bool { +func (X86Features) SHA() bool { return cpu.X86.HasSHA } diff --git a/src/simd/internal/simd_test/binary_test.go b/src/simd/internal/simd_test/binary_test.go index c82bc070e12..04dca3e2e2e 100644 --- a/src/simd/internal/simd_test/binary_test.go +++ b/src/simd/internal/simd_test/binary_test.go @@ -35,7 +35,7 @@ func TestAdd(t *testing.T) { testUint8x16Binary(t, simd.Uint8x16.Add, addSlice[uint8]) testUint8x32Binary(t, simd.Uint8x32.Add, addSlice[uint8]) - if simd.HasAVX512() { + if simd.X86.AVX512() { testFloat32x16Binary(t, simd.Float32x16.Add, addSlice[float32]) testFloat64x8Binary(t, simd.Float64x8.Add, addSlice[float64]) testInt8x64Binary(t, simd.Int8x64.Add, addSlice[int8]) @@ -73,7 +73,7 @@ func TestSub(t *testing.T) { testUint8x16Binary(t, simd.Uint8x16.Sub, subSlice[uint8]) testUint8x32Binary(t, simd.Uint8x32.Sub, subSlice[uint8]) - if simd.HasAVX512() { + if simd.X86.AVX512() { testFloat32x16Binary(t, simd.Float32x16.Sub, subSlice[float32]) testFloat64x8Binary(t, simd.Float64x8.Sub, subSlice[float64]) testInt8x64Binary(t, simd.Int8x64.Sub, subSlice[int8]) @@ -98,7 +98,7 @@ func TestMax(t *testing.T) { testInt32x4Binary(t, simd.Int32x4.Max, maxSlice[int32]) testInt32x8Binary(t, simd.Int32x8.Max, maxSlice[int32]) - if simd.HasAVX512() { + if simd.X86.AVX512() { testInt64x2Binary(t, simd.Int64x2.Max, maxSlice[int64]) testInt64x4Binary(t, simd.Int64x4.Max, maxSlice[int64]) } @@ -111,7 +111,7 @@ func TestMax(t *testing.T) { testUint32x4Binary(t, simd.Uint32x4.Max, maxSlice[uint32]) testUint32x8Binary(t, simd.Uint32x8.Max, maxSlice[uint32]) - if simd.HasAVX512() { + if simd.X86.AVX512() { testUint64x2Binary(t, simd.Uint64x2.Max, maxSlice[uint64]) testUint64x4Binary(t, simd.Uint64x4.Max, maxSlice[uint64]) } @@ -119,7 +119,7 @@ func TestMax(t *testing.T) { testUint8x16Binary(t, simd.Uint8x16.Max, maxSlice[uint8]) testUint8x32Binary(t, simd.Uint8x32.Max, maxSlice[uint8]) - if simd.HasAVX512() { + if simd.X86.AVX512() { // testFloat32x16Binary(t, simd.Float32x16.Max, maxSlice[float32]) // nan is wrong // testFloat64x8Binary(t, simd.Float64x8.Max, maxSlice[float64]) // nan is wrong testInt8x64Binary(t, simd.Int8x64.Max, maxSlice[int8]) @@ -144,7 +144,7 @@ func TestMin(t *testing.T) { testInt32x4Binary(t, simd.Int32x4.Min, minSlice[int32]) testInt32x8Binary(t, simd.Int32x8.Min, minSlice[int32]) - if simd.HasAVX512() { + if simd.X86.AVX512() { testInt64x2Binary(t, simd.Int64x2.Min, minSlice[int64]) testInt64x4Binary(t, simd.Int64x4.Min, minSlice[int64]) } @@ -157,7 +157,7 @@ func TestMin(t *testing.T) { testUint32x4Binary(t, simd.Uint32x4.Min, minSlice[uint32]) testUint32x8Binary(t, simd.Uint32x8.Min, minSlice[uint32]) - if simd.HasAVX512() { + if simd.X86.AVX512() { testUint64x2Binary(t, simd.Uint64x2.Min, minSlice[uint64]) testUint64x4Binary(t, simd.Uint64x4.Min, minSlice[uint64]) } @@ -165,7 +165,7 @@ func TestMin(t *testing.T) { testUint8x16Binary(t, simd.Uint8x16.Min, minSlice[uint8]) testUint8x32Binary(t, simd.Uint8x32.Min, minSlice[uint8]) - if simd.HasAVX512() { + if simd.X86.AVX512() { // testFloat32x16Binary(t, simd.Float32x16.Min, minSlice[float32]) // nan is wrong // testFloat64x8Binary(t, simd.Float64x8.Min, minSlice[float64]) // nan is wrong testInt8x64Binary(t, simd.Int8x64.Min, minSlice[int8]) @@ -198,7 +198,7 @@ func TestAnd(t *testing.T) { testUint8x16Binary(t, simd.Uint8x16.And, andSlice[uint8]) testUint8x32Binary(t, simd.Uint8x32.And, andSlice[uint8]) - if simd.HasAVX512() { + if simd.X86.AVX512() { // testInt8x64Binary(t, simd.Int8x64.And, andISlice[int8]) // missing // testInt16x32Binary(t, simd.Int16x32.And, andISlice[int16]) // missing testInt32x16Binary(t, simd.Int32x16.And, andSlice[int32]) @@ -229,7 +229,7 @@ func TestAndNot(t *testing.T) { testUint8x16Binary(t, simd.Uint8x16.AndNot, andNotSlice[uint8]) testUint8x32Binary(t, simd.Uint8x32.AndNot, andNotSlice[uint8]) - if simd.HasAVX512() { + if simd.X86.AVX512() { testInt8x64Binary(t, simd.Int8x64.AndNot, andNotSlice[int8]) testInt16x32Binary(t, simd.Int16x32.AndNot, andNotSlice[int16]) testInt32x16Binary(t, simd.Int32x16.AndNot, andNotSlice[int32]) @@ -260,7 +260,7 @@ func TestXor(t *testing.T) { testUint8x16Binary(t, simd.Uint8x16.Xor, xorSlice[uint8]) testUint8x32Binary(t, simd.Uint8x32.Xor, xorSlice[uint8]) - if simd.HasAVX512() { + if simd.X86.AVX512() { // testInt8x64Binary(t, simd.Int8x64.Xor, andISlice[int8]) // missing // testInt16x32Binary(t, simd.Int16x32.Xor, andISlice[int16]) // missing testInt32x16Binary(t, simd.Int32x16.Xor, xorSlice[int32]) @@ -291,7 +291,7 @@ func TestOr(t *testing.T) { testUint8x16Binary(t, simd.Uint8x16.Or, orSlice[uint8]) testUint8x32Binary(t, simd.Uint8x32.Or, orSlice[uint8]) - if simd.HasAVX512() { + if simd.X86.AVX512() { // testInt8x64Binary(t, simd.Int8x64.Or, andISlice[int8]) // missing // testInt16x32Binary(t, simd.Int16x32.Or, andISlice[int16]) // missing testInt32x16Binary(t, simd.Int32x16.Or, orSlice[int32]) @@ -328,7 +328,7 @@ func TestMul(t *testing.T) { // testUint8x16Binary(t, simd.Uint8x16.Mul, mulSlice[uint8]) // nope // testUint8x32Binary(t, simd.Uint8x32.Mul, mulSlice[uint8]) - if simd.HasAVX512() { + if simd.X86.AVX512() { testInt64x2Binary(t, simd.Int64x2.Mul, mulSlice[int64]) // avx512 only testInt64x4Binary(t, simd.Int64x4.Mul, mulSlice[int64]) @@ -354,7 +354,7 @@ func TestDiv(t *testing.T) { testFloat64x2Binary(t, simd.Float64x2.Div, divSlice[float64]) testFloat64x4Binary(t, simd.Float64x4.Div, divSlice[float64]) - if simd.HasAVX512() { + if simd.X86.AVX512() { testFloat32x16Binary(t, simd.Float32x16.Div, divSlice[float32]) testFloat64x8Binary(t, simd.Float64x8.Div, divSlice[float64]) } diff --git a/src/simd/internal/simd_test/compare_test.go b/src/simd/internal/simd_test/compare_test.go index f8526d27e98..09b3bfc0d96 100644 --- a/src/simd/internal/simd_test/compare_test.go +++ b/src/simd/internal/simd_test/compare_test.go @@ -13,7 +13,7 @@ import ( // AVX 2 lacks most comparisons, but they can be synthesized // from > and = -var comparisonFixed bool = simd.HasAVX512() +var comparisonFixed bool = simd.X86.AVX512() func TestLess(t *testing.T) { testFloat32x4Compare(t, simd.Float32x4.Less, lessSlice[float32]) @@ -48,7 +48,7 @@ func TestLess(t *testing.T) { testUint8x16Compare(t, simd.Uint8x16.Less, lessSlice[uint8]) testUint8x32Compare(t, simd.Uint8x32.Less, lessSlice[uint8]) - if simd.HasAVX512() { + if simd.X86.AVX512() { testUint16x16Compare(t, simd.Uint16x16.Less, lessSlice[uint16]) testUint16x8Compare(t, simd.Uint16x8.Less, lessSlice[uint16]) testUint32x4Compare(t, simd.Uint32x4.Less, lessSlice[uint32]) @@ -95,7 +95,7 @@ func TestLessEqual(t *testing.T) { testUint8x16Compare(t, simd.Uint8x16.LessEqual, lessEqualSlice[uint8]) testUint8x32Compare(t, simd.Uint8x32.LessEqual, lessEqualSlice[uint8]) - if simd.HasAVX512() { + if simd.X86.AVX512() { testFloat32x16Compare(t, simd.Float32x16.LessEqual, lessEqualSlice[float32]) testFloat64x8Compare(t, simd.Float64x8.LessEqual, lessEqualSlice[float64]) testInt8x64Compare(t, simd.Int8x64.LessEqual, lessEqualSlice[int8]) @@ -135,7 +135,7 @@ func TestGreater(t *testing.T) { testUint8x16Compare(t, simd.Uint8x16.Greater, greaterSlice[uint8]) testUint8x32Compare(t, simd.Uint8x32.Greater, greaterSlice[uint8]) - if simd.HasAVX512() { + if simd.X86.AVX512() { testFloat32x16Compare(t, simd.Float32x16.Greater, greaterSlice[float32]) testFloat64x8Compare(t, simd.Float64x8.Greater, greaterSlice[float64]) @@ -174,7 +174,7 @@ func TestGreaterEqual(t *testing.T) { testUint8x16Compare(t, simd.Uint8x16.GreaterEqual, greaterEqualSlice[uint8]) testUint8x32Compare(t, simd.Uint8x32.GreaterEqual, greaterEqualSlice[uint8]) - if simd.HasAVX512() { + if simd.X86.AVX512() { testFloat32x16Compare(t, simd.Float32x16.GreaterEqual, greaterEqualSlice[float32]) testFloat64x8Compare(t, simd.Float64x8.GreaterEqual, greaterEqualSlice[float64]) testInt8x64Compare(t, simd.Int8x64.GreaterEqual, greaterEqualSlice[int8]) @@ -212,7 +212,7 @@ func TestEqual(t *testing.T) { testUint8x16Compare(t, simd.Uint8x16.Equal, equalSlice[uint8]) testUint8x32Compare(t, simd.Uint8x32.Equal, equalSlice[uint8]) - if simd.HasAVX512() { + if simd.X86.AVX512() { testFloat32x16Compare(t, simd.Float32x16.Equal, equalSlice[float32]) testFloat64x8Compare(t, simd.Float64x8.Equal, equalSlice[float64]) testInt8x64Compare(t, simd.Int8x64.Equal, equalSlice[int8]) @@ -250,7 +250,7 @@ func TestNotEqual(t *testing.T) { testUint8x16Compare(t, simd.Uint8x16.NotEqual, notEqualSlice[uint8]) testUint8x32Compare(t, simd.Uint8x32.NotEqual, notEqualSlice[uint8]) - if simd.HasAVX512() { + if simd.X86.AVX512() { testFloat32x16Compare(t, simd.Float32x16.NotEqual, notEqualSlice[float32]) testFloat64x8Compare(t, simd.Float64x8.NotEqual, notEqualSlice[float64]) testInt8x64Compare(t, simd.Int8x64.NotEqual, notEqualSlice[int8]) diff --git a/src/simd/internal/simd_test/simd_test.go b/src/simd/internal/simd_test/simd_test.go index f3492170e9e..a15925dbfa3 100644 --- a/src/simd/internal/simd_test/simd_test.go +++ b/src/simd/internal/simd_test/simd_test.go @@ -38,8 +38,8 @@ func TestType(t *testing.T) { v.y = &y sink = y - if !simd.HasAVX512GFNI() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512GFNI() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } v.z = maskT(simd.Mask32x4FromBits(0b0011)) @@ -111,8 +111,8 @@ func TestReflectMethod(t *testing.T) { } func TestVectorConversion(t *testing.T) { - if !simd.HasAVX512GFNI() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512GFNI() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } xv := [4]int32{1, 2, 3, 4} @@ -129,8 +129,8 @@ func TestVectorConversion(t *testing.T) { } func TestMaskConversion(t *testing.T) { - if !simd.HasAVX512GFNI() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512GFNI() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } x := simd.LoadInt32x4Slice([]int32{5, 0, 7, 0}) @@ -147,8 +147,8 @@ func TestMaskConversion(t *testing.T) { } func TestPermute(t *testing.T) { - if !simd.HasAVX512() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } x := []int64{1, 2, 3, 4, 5, 6, 7, 8} @@ -164,8 +164,8 @@ func TestPermute(t *testing.T) { } func TestPermute2(t *testing.T) { - if !simd.HasAVX512() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } x := []int64{1, 2, 3, 4, 5, 6, 7, 8} @@ -182,8 +182,8 @@ func TestPermute2(t *testing.T) { } func TestCompress(t *testing.T) { - if !simd.HasAVX512() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } v1234 := simd.LoadInt32x4Slice([]int32{1, 2, 3, 4}) @@ -197,8 +197,8 @@ func TestCompress(t *testing.T) { } func TestExpand(t *testing.T) { - if !simd.HasAVX512() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } v3400 := simd.LoadInt32x4Slice([]int32{3, 4, 0, 0}) @@ -333,8 +333,8 @@ func testMergeLocalswrapper(t *testing.T, op func(simd.Int64x4, simd.Int64x4) si } func TestBitMaskFromBits(t *testing.T) { - if !simd.HasAVX512() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } results := [2]int64{} @@ -351,8 +351,8 @@ func TestBitMaskFromBits(t *testing.T) { var maskForTestBitMaskFromBitsLoad = uint8(0b10) func TestBitMaskFromBitsLoad(t *testing.T) { - if !simd.HasAVX512() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } results := [2]int64{} @@ -367,8 +367,8 @@ func TestBitMaskFromBitsLoad(t *testing.T) { } func TestBitMaskToBits(t *testing.T) { - if !simd.HasAVX512() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } if v := simd.LoadInt16x8Slice([]int16{1, 0, 1, 0, 0, 0, 0, 0}).ToMask().ToBits(); v != 0b101 { @@ -379,8 +379,8 @@ func TestBitMaskToBits(t *testing.T) { var maskForTestBitMaskFromBitsStore uint8 func TestBitMaskToBitsStore(t *testing.T) { - if !simd.HasAVX512() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } maskForTestBitMaskFromBitsStore = simd.LoadInt16x8Slice([]int16{1, 0, 1, 0, 0, 0, 0, 0}).ToMask().ToBits() @@ -406,8 +406,8 @@ func TestMergeFloat(t *testing.T) { } func TestMergeFloat512(t *testing.T) { - if !simd.HasAVX512() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } @@ -433,8 +433,8 @@ func TestMergeFloat512(t *testing.T) { var ro uint8 = 2 func TestRotateAllVariable(t *testing.T) { - if !simd.HasAVX512() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } got := make([]int32, 4) @@ -487,8 +487,8 @@ func TestBroadcastInt8x32(t *testing.T) { } func TestMaskOpt512(t *testing.T) { - if !simd.HasAVX512() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } @@ -534,8 +534,8 @@ func TestFlattenedTranspose(t *testing.T) { func TestClearAVXUpperBits(t *testing.T) { // Test that ClearAVXUpperBits is safe even if there are SIMD values // alive (although usually one should not do this). - if !simd.HasAVX2() { - t.Skip("Test requires HasAVX2, not available on this hardware") + if !simd.X86.AVX2() { + t.Skip("Test requires X86.AVX2, not available on this hardware") return } @@ -554,8 +554,8 @@ func TestClearAVXUpperBits(t *testing.T) { } func TestLeadingZeros(t *testing.T) { - if !simd.HasAVX512() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } @@ -755,8 +755,8 @@ func TestSelect4FromPairConstGrouped(t *testing.T) { } func TestSelectFromPairConstGroupedUint32x16(t *testing.T) { - if !simd.HasAVX512() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } x := simd.LoadUint32x16Slice([]uint32{0, 1, 2, 3, 10, 11, 12, 13, 20, 21, 22, 23, 30, 31, 32, 33}) @@ -976,8 +976,8 @@ func TestSelect2FromPairConstGroupedInt(t *testing.T) { } func TestSelect2FromPairConstGroupedInt512(t *testing.T) { - if !simd.HasAVX512() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } @@ -1068,8 +1068,8 @@ func applyTo4(x, y, z, w simd.Int32x16, f func(x, y, z, w int32) int32) []int32 } func TestSelectTernOptInt32x16(t *testing.T) { - if !simd.HasAVX512() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } ax := []int32{0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1} @@ -1116,7 +1116,7 @@ func TestMaskedMerge(t *testing.T) { res := make([]int64, 4) expected := []int64{6, 8, -3, -4} mask := x.Less(y) - if simd.HasAVX512() { + if simd.X86.AVX512() { x.Add(y).Merge(z, mask).StoreSlice(res) } else { x.Add(y).Merge(z, mask).StoreSlice(res) diff --git a/src/simd/internal/simd_test/slicepart_test.go b/src/simd/internal/simd_test/slicepart_test.go index 07869e954b3..b7a4a4f71b1 100644 --- a/src/simd/internal/simd_test/slicepart_test.go +++ b/src/simd/internal/simd_test/slicepart_test.go @@ -345,8 +345,8 @@ func TestSlicePartFloat32(t *testing.T) { // 512-bit load func TestSlicePartInt64(t *testing.T) { - if !simd.HasAVX512() { - t.Skip("Test requires HasAVX512, not available on this hardware") + if !simd.X86.AVX512() { + t.Skip("Test requires X86.AVX512, not available on this hardware") return } diff --git a/src/simd/internal/simd_test/ternary_test.go b/src/simd/internal/simd_test/ternary_test.go index 2374635917d..6b563cef752 100644 --- a/src/simd/internal/simd_test/ternary_test.go +++ b/src/simd/internal/simd_test/ternary_test.go @@ -12,7 +12,7 @@ import ( ) func TestFMA(t *testing.T) { - if simd.HasAVX512() { + if simd.X86.AVX512() { testFloat32x4TernaryFlaky(t, simd.Float32x4.MulAdd, fmaSlice[float32], 0.001) testFloat32x8TernaryFlaky(t, simd.Float32x8.MulAdd, fmaSlice[float32], 0.001) testFloat32x16TernaryFlaky(t, simd.Float32x16.MulAdd, fmaSlice[float32], 0.001) diff --git a/src/simd/internal/simd_test/unary_test.go b/src/simd/internal/simd_test/unary_test.go index 1f89beb7850..4fb197700b3 100644 --- a/src/simd/internal/simd_test/unary_test.go +++ b/src/simd/internal/simd_test/unary_test.go @@ -17,7 +17,7 @@ func TestCeil(t *testing.T) { testFloat32x8Unary(t, simd.Float32x8.Ceil, ceilSlice[float32]) testFloat64x2Unary(t, simd.Float64x2.Ceil, ceilSlice[float64]) testFloat64x4Unary(t, simd.Float64x4.Ceil, ceilSlice[float64]) - if simd.HasAVX512() { + if simd.X86.AVX512() { // testFloat32x16Unary(t, simd.Float32x16.Ceil, ceilSlice[float32]) // missing // testFloat64x8Unary(t, simd.Float64x8.Ceil, ceilSlice[float64]) // missing } @@ -28,7 +28,7 @@ func TestFloor(t *testing.T) { testFloat32x8Unary(t, simd.Float32x8.Floor, floorSlice[float32]) testFloat64x2Unary(t, simd.Float64x2.Floor, floorSlice[float64]) testFloat64x4Unary(t, simd.Float64x4.Floor, floorSlice[float64]) - if simd.HasAVX512() { + if simd.X86.AVX512() { // testFloat32x16Unary(t, simd.Float32x16.Floor, floorSlice[float32]) // missing // testFloat64x8Unary(t, simd.Float64x8.Floor, floorSlice[float64]) // missing } @@ -39,7 +39,7 @@ func TestTrunc(t *testing.T) { testFloat32x8Unary(t, simd.Float32x8.Trunc, truncSlice[float32]) testFloat64x2Unary(t, simd.Float64x2.Trunc, truncSlice[float64]) testFloat64x4Unary(t, simd.Float64x4.Trunc, truncSlice[float64]) - if simd.HasAVX512() { + if simd.X86.AVX512() { // testFloat32x16Unary(t, simd.Float32x16.Trunc, truncSlice[float32]) // missing // testFloat64x8Unary(t, simd.Float64x8.Trunc, truncSlice[float64]) // missing } @@ -50,7 +50,7 @@ func TestRound(t *testing.T) { testFloat32x8Unary(t, simd.Float32x8.RoundToEven, roundSlice[float32]) testFloat64x2Unary(t, simd.Float64x2.RoundToEven, roundSlice[float64]) testFloat64x4Unary(t, simd.Float64x4.RoundToEven, roundSlice[float64]) - if simd.HasAVX512() { + if simd.X86.AVX512() { // testFloat32x16Unary(t, simd.Float32x16.Round, roundSlice[float32]) // missing // testFloat64x8Unary(t, simd.Float64x8.Round, roundSlice[float64]) // missing } @@ -61,7 +61,7 @@ func TestSqrt(t *testing.T) { testFloat32x8Unary(t, simd.Float32x8.Sqrt, sqrtSlice[float32]) testFloat64x2Unary(t, simd.Float64x2.Sqrt, sqrtSlice[float64]) testFloat64x4Unary(t, simd.Float64x4.Sqrt, sqrtSlice[float64]) - if simd.HasAVX512() { + if simd.X86.AVX512() { testFloat32x16Unary(t, simd.Float32x16.Sqrt, sqrtSlice[float32]) testFloat64x8Unary(t, simd.Float64x8.Sqrt, sqrtSlice[float64]) } @@ -83,7 +83,7 @@ func TestAbsolute(t *testing.T) { testInt16x16Unary(t, simd.Int16x16.Abs, map1[int16](abs)) testInt32x4Unary(t, simd.Int32x4.Abs, map1[int32](abs)) testInt32x8Unary(t, simd.Int32x8.Abs, map1[int32](abs)) - if simd.HasAVX512() { + if simd.X86.AVX512() { testInt8x64Unary(t, simd.Int8x64.Abs, map1[int8](abs)) testInt16x32Unary(t, simd.Int16x32.Abs, map1[int16](abs)) testInt32x16Unary(t, simd.Int32x16.Abs, map1[int32](abs)) @@ -94,7 +94,7 @@ func TestAbsolute(t *testing.T) { } func TestCeilScaledResidue(t *testing.T) { - if !simd.HasAVX512() { + if !simd.X86.AVX512() { t.Skip("Needs AVX512") } testFloat64x8UnaryFlaky(t, @@ -111,7 +111,7 @@ func TestCeilScaledResidue(t *testing.T) { } func TestToUint32(t *testing.T) { - if !simd.HasAVX512() { + if !simd.X86.AVX512() { t.Skip("Needs AVX512") } testFloat32x4ConvertToUint32(t, simd.Float32x4.ConvertToUint32, map1[float32](toUint32)) @@ -130,7 +130,7 @@ func TestConverts(t *testing.T) { } func TestConvertsAVX512(t *testing.T) { - if !simd.HasAVX512() { + if !simd.X86.AVX512() { t.Skip("Needs AVX512") } testUint8x32ConvertToUint16(t, simd.Uint8x32.ConvertToUint16, map1[uint8](toUint16)) diff --git a/src/simd/pkginternal_test.go b/src/simd/pkginternal_test.go index c5b46eb0d96..baaafdbdc11 100644 --- a/src/simd/pkginternal_test.go +++ b/src/simd/pkginternal_test.go @@ -48,7 +48,7 @@ func TestConcatSelectedConstantGrouped32(t *testing.T) { } func TestTern(t *testing.T) { - if !HasAVX512() { + if !X86.AVX512() { t.Skip("This test needs AVX512") } x := LoadInt32x8Slice([]int32{0, 0, 0, 0, 1, 1, 1, 1}) diff --git a/test/codegen/simd.go b/test/codegen/simd.go index 53f93c5af64..63d5bf757a2 100644 --- a/test/codegen/simd.go +++ b/test/codegen/simd.go @@ -60,7 +60,7 @@ func simdArrayWrapperNoSpill(a [1]Args2) simd.Uint8x32 { func simdFeatureGuardedMaskOpt() simd.Int16x16 { var x, y simd.Int16x16 - if simd.HasAVX512() { + if simd.X86.AVX512() { mask := simd.Mask16x16FromBits(5) return x.Add(y).Masked(mask) // amd64:`VPADDW.Z\s.*$` } @@ -70,7 +70,7 @@ func simdFeatureGuardedMaskOpt() simd.Int16x16 { func simdMaskedMerge() simd.Int16x16 { var x, y simd.Int16x16 - if simd.HasAVX512() { + if simd.X86.AVX512() { mask := simd.Mask16x16FromBits(5) return x.Add(y).Merge(x, mask) // amd64:-`VPBLENDVB\s.*$` } diff --git a/test/simd.go b/test/simd.go index 307e98e0e7f..087f6e3da1e 100644 --- a/test/simd.go +++ b/test/simd.go @@ -44,12 +44,12 @@ var a int func f() { if a == 0 { - if !simd.HasAVX512() { + if !simd.X86.AVX512() { return } println("has avx512") // ERROR "has features avx[+]avx2[+]avx512$" } else { - if !simd.HasAVX2() { + if !simd.X86.AVX2() { return } println("has avx2") // ERROR "has features avx[+]avx2$" @@ -58,7 +58,7 @@ func f() { } // ERROR "has features avx[+]avx2$" func g() { - if simd.HasAVX2() { // ERROR "has features avx[+]avx2$" + if simd.X86.AVX2() { // ERROR "has features avx[+]avx2$" for range 5 { // ERROR "has features avx[+]avx2$" if a < 0 { // ERROR "has features avx[+]avx2$" a++ // ERROR "has features avx[+]avx2$" @@ -77,7 +77,7 @@ func p() bool { } func hasIrreducibleLoop() { - if simd.HasAVX2() { + if simd.X86.AVX2() { goto a // ERROR "has features avx[+]avx2$" } else { goto b @@ -97,7 +97,7 @@ c: } func ternRewrite(m, w, x, y, z simd.Int32x16) (t0, t1, t2 simd.Int32x16) { - if !simd.HasAVX512() { // ERROR "has features avx[+]avx2[+]avx512$" + if !simd.X86.AVX512() { // ERROR "has features avx[+]avx2[+]avx512$" return // ERROR "has features avx[+]avx2[+]avx512$" // all blocks have it because of the vector size } t0 = w.Xor(y).Xor(z) // ERROR "Rewriting.*ternInt" @@ -111,7 +111,7 @@ func ternTricky1(x, y, z simd.Int32x8) simd.Int32x8 { // a is a 3-variable logical expression occurring outside AVX-512 feature check a := x.Xor(y).Xor(z) var w simd.Int32x8 - if !simd.HasAVX512() { // ERROR "has features avx$" + if !simd.X86.AVX512() { // ERROR "has features avx$" // do nothing } else { w = y.AndNot(a) // ERROR "has features avx[+]avx2[+]avx512" "Rewriting.*ternInt" @@ -123,7 +123,7 @@ func ternTricky1(x, y, z simd.Int32x8) simd.Int32x8 { func ternTricky2(x, y, z simd.Int32x8) simd.Int32x8 { // Int32x8 is a 256-bit vector and does not guarantee AVX-512 var a, w simd.Int32x8 - if !simd.HasAVX512() { // ERROR "has features avx$" + if !simd.X86.AVX512() { // ERROR "has features avx$" // do nothing } else { a = x.Xor(y).Xor(z) @@ -137,7 +137,7 @@ func ternTricky3(x, y, z simd.Int32x8) simd.Int32x8 { // Int32x8 is a 256-bit vector and does not guarantee AVX-512 a := x.Xor(y).Xor(z) w := y.AndNot(a) - if !simd.HasAVX512() { // ERROR "has features avx$" + if !simd.X86.AVX512() { // ERROR "has features avx$" return a // ERROR "has features avx$" } // a is a common subexpression