[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 <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Junyang Shao 2025-11-12 19:56:09 +00:00
parent e4d9484220
commit 934dbcea1a
11 changed files with 134 additions and 126 deletions

View file

@ -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}}

View file

@ -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
}

View file

@ -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])
}

View file

@ -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])

View file

@ -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)

View file

@ -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
}

View file

@ -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)

View file

@ -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))

View file

@ -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})

View file

@ -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.*$`
}

View file

@ -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