Repository navigation
cmd/compile: lack of carryless multiply on AMD64 constrains SIMD vector width #81884
Description
Go version
go version go1.28-devel_f91ce18c4d linux/amd64
Output of go env in your module/workspace:
AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN='/usr/local/google/home/sjmuir/go/bin'
GOCACHE='/usr/local/google/home/sjmuir/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/usr/local/google/home/sjmuir/.config/go/env'
GOEXE=''
GOEXPERIMENT='simd'
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1079225976=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/usr/local/google/home/sjmuir/go/git/go-tip/src/go.mod'
GOMODCACHE='/usr/local/google/home/sjmuir/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPACKAGESDRIVER=''
GOPATH='/usr/local/google/home/sjmuir/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/google/home/sjmuir/go/git/go-tip'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/usr/local/google/home/sjmuir/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/google/home/sjmuir/go/git/go-tip/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.28-devel_f91ce18c4d Tue Sep 29 10:28:05 2026 -0700'
GOWORK=''
PKG_CONFIG='pkg-config'What did you do?
I observed that there is some subset of AMD64 platforms that have AVX-2 support (introduced in Haswell, 2013), i.e., 256-bit wide vectors, but lack 256-bit carryless multiply instructions (CLMUL, introduced in Ice Lake, 2019, and Zen 3, 2020), which causes the runtime selection of vector size to fall back to 128 bits.
What did you see happen?
At runtime on an affected platform the SIMD vector width is set to 128 bits rather than 256 bits.
This can be overridden using GODEBUG="simd=+", which indicates that the user asserts that carryless multiply instructions are not used in their code. However, any use of CLMUL instructions will cause the program to be killed with SIGILL.
What did you expect to see?
A user of an affected platform might expect to get 256-bit vectors and be stumped as to why they didn't, since it is somewhat non-obvious: it would be nice to have emulated CLMUL instructions so that programs could safely use 256-bit vectors regardless of whether CLMUL is actually used or not (which might be ~unknown to the typical user given transitive dependencies and all that).
I would not expect this to be the highest priority gap to address. However, it could be implemented in the same way that it is done on ARM64 platforms without CLMUL, by emulating the missing instructions.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTodo
Activity
9muir commentedon Sep 30, 2026
This issue also afflicts Intel platforms - Skylake SP (1st gen "Xeon Scalable", introduced 2017), Cascade Lake SP/X/W (2nd gen), and Cooper Lake SP (3rd gen, 4S/8S) - that have AVX-512 support but lack either 512-bit or 256-bit CLMUL, and get downgraded to 128-bit.
dr2chase commentedon Sep 30, 2026
Arm64 was a higher priority, because there's no fallback other than full emulation. On amd64, there's 128-bit, which is well faster than emulated.
9muir commentedon Sep 30, 2026
Public cloud data that's publicly available (unfortunately lacking any sort of proportion-of-fleet numbers, for obvious reasons):