Skip to content

cmd/compile: inconsistent integer arithmetic result on Go 1.22+arm64 with/without -race #68227

@mathetake

Description

@mathetake

Go version

go version go1.22.3 darwin/arm64

Output of go env in your module/workspace:

GO111MODULE='on'
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/mathetake/Library/Caches/go-build'
GOENV='/Users/mathetake/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/mathetake/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/mathetake/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.22.3'
GCCGO='gccgo'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/Users/mathetake/wazero/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/zv/cj1015lx5bndpw3n_qsx9mh40000gn/T/go-build2746109211=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

The following is the small repro that I managed to craft, and I run go test . and go test -race ..

type someType []uint64

func (s *someType) push(v uint64) {
	*s = append(*s, v)
}

func (s *someType) problematicFn(x1Lo, x1Hi, x2Lo, x2Hi uint64) {
	r1 := int32(int16(x1Lo>>0)) * int32(int16(x2Lo>>0))
	r3 := int32(int16(x1Lo>>32)) * int32(int16(x2Lo>>32))
	r4 := int32(int16(x1Lo>>48)) * int32(int16(x2Lo>>48))
	r5 := int32(int16(x1Hi>>0)) * int32(int16(x2Hi>>0))
	r7 := int32(int16(x1Hi>>32)) * int32(int16(x2Hi>>32))
	r8 := int32(int16(x1Hi>>48)) * int32(int16(x2Hi>>48))
	s.push(uint64(uint32(r1)) | (uint64(uint32(r3+r4)) << 32))
	s.push(uint64(uint32(r5)) | (uint64(uint32(r7+r8)) << 32))
}

func TestProblematicFn(t *testing.T) {
	s := &someType{}
	s.problematicFn(281479271743489, 281479271743489, 18446744073709551615, 18446744073709551615)
	if (*s)[0] != 18446744069414584319 {
		t.Fatal("unexpected result")
	}
	if (*s)[1] != 18446744073709551615 {
		t.Fatal("unexpected result")
	}
}

What did you see happen?

I got the assertion failure only for the case with -race. Note that this also happens for linux/arm64 but only when Go 1.22.
When I briefly run with the different Go version, I got the consistent result but the assertion was failing, meaning that the compiled machine code has some undefined behavior. I suspect that seems the root case.

What did you expect to see?

Consistent results regardless of with or withour -race flag.

Metadata

Metadata

Assignees

Labels

CriticalA critical problem that affects the availability or correctness of production systems built using GoFrozenDueToAgearch-arm64compiler/runtimeIssues related to the Go compiler and/or runtime.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions