Repository navigation
cmd/compile: floating-point archsimd Min/Max incorrectly treated as commutative on amd64 #81468
Description
Go version
go version go1.28-devel_22fde194 Tue Sep 1 11:14:31 2026 -0700 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='0'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='<redacted>'
GOCACHEPROG=''
GODEBUG=''
GOENV=''
GOEXE=''
GOEXPERIMENT='simd'
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=<redacted>=<redacted> -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE=''
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPACKAGESDRIVER=''
GOPATH=''
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='<redacted>'
GOSUMDB='sum.golang.org'
GOTELEMETRY='off'
GOTELEMETRYDIR=''
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='<redacted>/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.28-devel_22fde194 Tue Sep 1 11:14:31 2026 -0700'
GOWORK=''
PKG_CONFIG='pkg-config'What did you do?
I built the dev.simd branch at 22fde194033d4d969811153efbc06d71f95ee819 and ran this program with GOEXPERIMENT=simd go run main.go on a machine with AVX support:
package main
import (
"fmt"
"math"
"simd/archsimd"
)
//go:noinline
func minBoth(x, y archsimd.Float32x4) (archsimd.Float32x4, archsimd.Float32x4) {
return x.Min(y), y.Min(x)
}
func bits(x archsimd.Float32x4) [4]uint32 {
var a [4]float32
x.StoreArray(&a)
return [4]uint32{
math.Float32bits(a[0]), math.Float32bits(a[1]),
math.Float32bits(a[2]), math.Float32bits(a[3]),
}
}
func main() {
if !archsimd.X86.AVX() {
panic("AVX is required")
}
a := [4]float32{math.Float32frombits(0x7fc00001), 1, math.Float32frombits(0x80000000), 0}
b := [4]float32{1, math.Float32frombits(0x7fc00002), 0, math.Float32frombits(0x80000000)}
x := archsimd.LoadFloat32x4Array(&a)
y := archsimd.LoadFloat32x4Array(&b)
xy, yx := minBoth(x, y)
fmt.Printf("x.Min(y): %08x\n", bits(xy))
fmt.Printf("y.Min(x): %08x\n", bits(yx))
}The same problem reproduces on the master branch at be1160f2a446665d6c0ccd2344c0cbe365bbc3a4.
What did you see happen?
The compiler produces the same result for both calls:
x.Min(y): [7fc00001 3f800000 80000000 00000000]
y.Min(x): [7fc00001 3f800000 80000000 00000000]
Replacing Min with Max has the same problem.
What did you expect to see?
The two calls should preserve their operand order:
x.Min(y): [3f800000 7fc00002 00000000 80000000]
y.Min(x): [7fc00001 3f800000 80000000 00000000]
On amd64 these methods lower to VMINPS/VMAXPS. Those instructions select the second source operand when either operand is NaN or when both operands are zero, so swapping the operands can change the result.
MinMax/categories.yaml currently marks Min and Max as commutative for both integer and floating-point vectors. CSE therefore merges the two calls above. This appears to be the same kind of metadata problem fixed for comparisons in #76632.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsIn Progress
Activity
gopherbot commentedon Sep 11, 2026
Change https://go.dev/cl/830865 mentions this issue:
[dev.simd] cmd/compile: preserve floating-point SIMD min/max ordergabyhelp commentedon Sep 11, 2026
Related Issues
Related Code Changes
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
JunyangShao commentedon Sep 11, 2026
@dr2chase
gopherbot commentedon Sep 13, 2026
Change https://go.dev/cl/831764 mentions this issue:
cmd/compile: preserve floating-point SIMD min/max orderzhouguangyuan0718 commentedon Sep 22, 2026
Could someone take a look at this issue and the patch? I'd like to know whether this approach seems reasonable or if there are any concerns with it.
Thanks!
tcka4enckoalexei2014-commits commentedon Sep 22, 2026
cmd/compile: preserve floating-point SIMD min/max order