]> Cypherpunks repositories - gostls13.git/commitdiff
internal/cpu: add AVX-512-CD and DQ, and derived "basic AVX-512"
authorAustin Clements <austin@google.com>
Thu, 12 Jun 2025 19:24:22 +0000 (15:24 -0400)
committerGopher Robot <gobot@golang.org>
Tue, 5 Aug 2025 20:57:45 +0000 (13:57 -0700)
This adds detection for the CD and DQ sub-features of x86 AVX-512.

Building on these, we also add a "derived" AVX-512 feature that
bundles together the basic usable subset of subfeatures. Despite the F
in AVX-512-F standing for "foundation", AVX-512-F+BW+DQ+VL together
really form the basic usable subset of AVX-512 functionality. These
have also all been supported together by almost every CPU, and are
guaranteed by GOAMD64=v4, so there's little point in separating them
out.

This is a cherry-pick of CL 680899 from the dev.simd branch.

Change-Id: I34356502bd1853ba2372e48db0b10d55cffe07a1
Reviewed-on: https://go-review.googlesource.com/c/go/+/693396
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Austin Clements <austin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/internal/cpu/cpu.go
src/internal/cpu/cpu_x86.go

index 6017b1acc9fe96f899396ad174c2c4e325e0910d..fca38532dc518f53bbbb21c13e36602a2ee59bd6 100644 (file)
@@ -31,9 +31,13 @@ var X86 struct {
        HasADX              bool
        HasAVX              bool
        HasAVX2             bool
+       HasAVX512           bool // Virtual feature: F+CD+BW+DQ+VL
        HasAVX512F          bool
+       HasAVX512CD         bool
        HasAVX512BW         bool
+       HasAVX512DQ         bool
        HasAVX512VL         bool
+       HasAVX512VPCLMULQDQ bool
        HasBMI1             bool
        HasBMI2             bool
        HasERMS             bool
@@ -48,7 +52,6 @@ var X86 struct {
        HasSSSE3            bool
        HasSSE41            bool
        HasSSE42            bool
-       HasAVX512VPCLMULQDQ bool
        _                   CacheLinePad
 }
 
@@ -161,6 +164,10 @@ var RISCV64 struct {
 //go:linkname S390X
 //go:linkname RISCV64
 
+// doDerived, if non-nil, is called after processing GODEBUG to set "derived"
+// feature flags.
+var doDerived func()
+
 // Initialize examines the processor and sets the relevant variables above.
 // This is called by the runtime package early in program initialization,
 // before normal init functions are run. env is set by runtime if the OS supports
@@ -168,6 +175,9 @@ var RISCV64 struct {
 func Initialize(env string) {
        doinit()
        processOptions(env)
+       if doDerived != nil {
+               doDerived()
+       }
 }
 
 // options contains the cpu debug options that can be used in GODEBUG.
index 69b9542ae2a1f504f7e99a0f438c9dd04bb25e86..315c26b0ddb735a76ae4d6f0d8452616ef8e6832 100644 (file)
@@ -36,7 +36,9 @@ const (
        cpuid_BMI2     = 1 << 8
        cpuid_ERMS     = 1 << 9
        cpuid_AVX512F  = 1 << 16
+       cpuid_AVX512DQ = 1 << 17
        cpuid_ADX      = 1 << 19
+       cpuid_AVX512CD = 1 << 28
        cpuid_SHA      = 1 << 29
        cpuid_AVX512BW = 1 << 30
        cpuid_AVX512VL = 1 << 31
@@ -89,7 +91,9 @@ func doinit() {
                // they can be turned off.
                options = append(options,
                        option{Name: "avx512f", Feature: &X86.HasAVX512F},
+                       option{Name: "avx512cd", Feature: &X86.HasAVX512CD},
                        option{Name: "avx512bw", Feature: &X86.HasAVX512BW},
+                       option{Name: "avx512dq", Feature: &X86.HasAVX512DQ},
                        option{Name: "avx512vl", Feature: &X86.HasAVX512VL},
                )
        }
@@ -154,7 +158,9 @@ func doinit() {
 
        X86.HasAVX512F = isSet(ebx7, cpuid_AVX512F) && osSupportsAVX512
        if X86.HasAVX512F {
+               X86.HasAVX512CD = isSet(ebx7, cpuid_AVX512CD)
                X86.HasAVX512BW = isSet(ebx7, cpuid_AVX512BW)
+               X86.HasAVX512DQ = isSet(ebx7, cpuid_AVX512DQ)
                X86.HasAVX512VL = isSet(ebx7, cpuid_AVX512VL)
                X86.HasAVX512VPCLMULQDQ = isSet(ecx7, cpuid_AVX512VPCLMULQDQ)
        }
@@ -170,6 +176,17 @@ func doinit() {
 
        _, _, _, edxExt1 := cpuid(0x80000001, 0)
        X86.HasRDTSCP = isSet(edxExt1, cpuid_RDTSCP)
+
+       doDerived = func() {
+               // Rather than carefully gating on fundamental AVX-512 features, we have
+               // a virtual "AVX512" feature that captures F+CD+BW+DQ+VL. BW, DQ, and
+               // VL have a huge effect on which AVX-512 instructions are available,
+               // and these have all been supported on everything except the earliest
+               // Phi chips with AVX-512. No CPU has had CD without F, so we include
+               // it. GOAMD64=v4 also implies exactly this set, and these are all
+               // included in AVX10.1.
+               X86.HasAVX512 = X86.HasAVX512F && X86.HasAVX512CD && X86.HasAVX512BW && X86.HasAVX512DQ && X86.HasAVX512VL
+       }
 }
 
 func isSet(hwc uint32, value uint32) bool {