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>
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}}
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
}
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])
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])
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])
}
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])
}
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])
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])
}
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])
}
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])
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])
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])
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])
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])
// 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])
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])
}
// 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])
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])
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])
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])
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])
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])
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])
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))
}
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}
}
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})
}
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}
}
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}
}
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})
}
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})
}
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{}
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{}
}
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 {
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()
}
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
}
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)
}
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
}
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
}
}
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
}
}
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})
}
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
}
}
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}
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)
// 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
}
)
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)
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
}
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
}
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
}
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
}
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])
}
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))
}
func TestCeilScaledResidue(t *testing.T) {
- if !simd.HasAVX512() {
+ if !simd.X86.AVX512() {
t.Skip("Needs AVX512")
}
testFloat64x8UnaryFlaky(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))
}
func TestConvertsAVX512(t *testing.T) {
- if !simd.HasAVX512() {
+ if !simd.X86.AVX512() {
t.Skip("Needs AVX512")
}
testUint8x32ConvertToUint16(t, simd.Uint8x32.ConvertToUint16, map1[uint8](toUint16))
}
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})
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.*$`
}
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.*$`
}
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$"
} // 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$"
}
func hasIrreducibleLoop() {
- if simd.HasAVX2() {
+ if simd.X86.AVX2() {
goto a // ERROR "has features avx[+]avx2$"
} else {
goto b
}
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"
// 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"
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)
// 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