Skip to content

simd: Less/Greater methods produce inconsistent results #76632

@eriklupander

Description

@eriklupander

What version of Go are you using (go version)?

go version go1.26-devel_f3a306527c1 Tue Nov 25 15:19:18 2025 -0800 darwin/amd64

Does this issue reproduce with the latest release?

N/A

What operating system and processor architecture are you using (go env)?

gotip env Output
$ gotip env
AR='ar'
CC='clang'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='clang++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/Users/username/Library/Caches/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/Users/username/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/9s/h91w8vqd2dxbp8htt1ht2gf80000gn/T/go-build2605401336=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOHOSTARCH='amd64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMOD='/Users/username/privat/simd-tracer/go.mod'
GOMODCACHE='/Users/username/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/username/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/Users/username/sdk/gotip'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/username/Library/Application Support/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/Users/username/sdk/gotip/pkg/tool/darwin_amd64'
GOVCS=''
GOVERSION='go1.26-devel_f3a306527c1 Tue Nov 25 15:19:18 2025 -0800'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

With the dev.simd experiment (#73787), I am seeing inconsistent results using the Less and Greater methods on Float32x8, i.e. producing masks. I discovered this issue while debugging (using IntelliJ IDEA) some code using the simd package, where running with the debugger consistently produced different results than plain running.

This was reproducible using gotip run -gcflags="-l -N" main.go versus gotip run main.go on the command-line.

I have posted an example on the Go Playground that showcases the inconsistent behaviour depending on whether inlining and/or optimizations are disabled or not:
https://go.dev/play/p/OSiuSpcTK9h

Please note that even small / subtle changes to the code above might produce correct results, such as:

  • Move the var zeroes declaration into the TryToReproduce() function.
  • Do one instead of two Less operations (e.g. remove v2 and m2).
  • Even inserting an intermediary fmt.Printf("v1: %v\n", v1) statement inside the function may "fix" the erroneous behaviour.

My assembly skills aren't good enough to identify what's going on with inlining disabled, or what differences in code that are causing this. Perhaps some register assignment is generated erroneously with the simd code under certain circumstances?

I've ran into the inconsistent results while coding (just for fun) some ray/sphere intersection code using the new simd package, so it seems to occur not solely under very specific circumstances.

What did you expect to see?

The various comparison methods produces inconsistent results, for example if building with/without inlining, but also sometimes depending on surrounding code.

Please see the linked Go Playground snippet for code. But basically, performing a Less operation on a Float32x8 having negative numbers such as [0, 0, -2, 0, 0, 0, 0, 0], with another Float32x8 having [0,0,0,0,0,0,0,0] as argument, is expected to output [0,0,-1,0,0,0,0,0].

What did you see instead?

Under certain circumstances (see "What did you do?" section), code similar to the above outputs [0,0,0,0,0,0,0,0]

Metadata

Metadata

Assignees

Labels

BugReportIssues describing a possible bug in the Go implementation.NeedsFixThe path to resolution is known, but the work has not been done.compiler/runtimeIssues related to the Go compiler and/or runtime.

Type

No type

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions