Skip to content

Commit b677753

Browse files
vsivsimartisch
authored andcommitted
cpu: fix AVX512 support detection on Darwin
Summary: On darwin/amd64, it is not adequate to use OSXSAVE bits to determine AVX512 availabilty. The reason is involved. See github issue for details. The fix consists of implementing Apple's recommended approach using the process commpage cpu_capabilities bits to determine availability of AVX512. Fixes golang/go#43089 Change-Id: I1ba89965498863d268fbf2e427dbfd6429c7409f Reviewed-on: https://go-review.googlesource.com/c/sys/+/285572 Trust: Tobias Klauser <[email protected]> Run-TryBot: Tobias Klauser <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Martin Möhrmann <[email protected]>
1 parent 71e4cd6 commit b677753

File tree

4 files changed

+42
-2
lines changed

4 files changed

+42
-2
lines changed

cpu/cpu_gc_x86.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
1515
// xgetbv with ecx = 0 is implemented in cpu_x86.s for gc compiler
1616
// and in cpu_gccgo.c for gccgo.
1717
func xgetbv() (eax, edx uint32)
18+
19+
// darwinSupportsAVX512 is implemented in cpu_x86.s for gc compiler
20+
// and in cpu_gccgo_x86.go for gccgo.
21+
func darwinSupportsAVX512() bool

cpu/cpu_gccgo_x86.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,9 @@ func xgetbv() (eax, edx uint32) {
2525
gccgoXgetbv(&a, &d)
2626
return a, d
2727
}
28+
29+
// gccgo doesn't build on Darwin, per:
30+
// https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/gcc.rb#L76
31+
func darwinSupportsAVX512() bool {
32+
return false
33+
}

cpu/cpu_x86.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,14 @@ func archInit() {
8787
// Check if XMM and YMM registers have OS support.
8888
osSupportsAVX = isSet(1, eax) && isSet(2, eax)
8989

90-
// Check if OPMASK and ZMM registers have OS support.
91-
osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && isSet(6, eax) && isSet(7, eax)
90+
if runtime.GOOS == "darwin" {
91+
// Check darwin commpage for AVX512 support. Necessary because:
92+
// https://github.com/apple/darwin-xnu/blob/0a798f6738bc1db01281fc08ae024145e84df927/osfmk/i386/fpu.c#L175-L201
93+
osSupportsAVX512 = osSupportsAVX && darwinSupportsAVX512()
94+
} else {
95+
// Check if OPMASK and ZMM registers have OS support.
96+
osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && isSet(6, eax) && isSet(7, eax)
97+
}
9298
}
9399

94100
X86.HasAVX = isSet(28, ecx1) && osSupportsAVX

cpu/cpu_x86.s

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,27 @@ TEXT ·xgetbv(SB),NOSPLIT,$0-8
2626
MOVL AX, eax+0(FP)
2727
MOVL DX, edx+4(FP)
2828
RET
29+
30+
// func darwinSupportsAVX512() bool
31+
TEXT ·darwinSupportsAVX512(SB), NOSPLIT, $0-1
32+
MOVB $0, ret+0(FP) // default to false
33+
#ifdef GOOS_darwin // return if not darwin
34+
#ifdef GOARCH_amd64 // return if not amd64
35+
// These values from:
36+
// https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/osfmk/i386/cpu_capabilities.h
37+
#define commpage64_base_address 0x00007fffffe00000
38+
#define commpage64_cpu_capabilities64 (commpage64_base_address+0x010)
39+
#define commpage64_version (commpage64_base_address+0x01E)
40+
#define hasAVX512F 0x0000004000000000
41+
MOVQ $commpage64_version, BX
42+
CMPW (BX), $13 // cpu_capabilities64 undefined in versions < 13
43+
JL no_avx512
44+
MOVQ $commpage64_cpu_capabilities64, BX
45+
MOVQ $hasAVX512F, CX
46+
TESTQ (BX), CX
47+
JZ no_avx512
48+
MOVB $1, ret+0(FP)
49+
no_avx512:
50+
#endif
51+
#endif
52+
RET

0 commit comments

Comments
 (0)