Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: uint32(math.NaN()) returns -1 on riscv64, but 0 on all other architectures #64917

Closed
anthonyfok opened this issue Jan 1, 2024 · 3 comments
Labels
arch-riscv Issues solely affecting the riscv64 architecture. compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.

Comments

@anthonyfok
Copy link

Go version

go version go1.21.5 linux/riscv64

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

GO111MODULE=''
GOARCH='riscv64'
GOBIN=''
GOCACHE='/home/debian/.cache/go-build'
GOENV='/home/debian/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='riscv64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/debian/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/debian/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/lib/go-1.21'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/lib/go-1.21/pkg/tool/linux_riscv64'
GOVCS=''
GOVERSION='go1.21.5'
GCCGO='gccgo'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
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 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build736585681=/tmp/go-build -gno-record-gcc-switches'

What did you do?

I am trying to find a solution this bug detected by Debian buildd: https://buildd.debian.org/status/package.php?p=golang-github-evanw-esbuild:

I have made a minimal reproducible example (MRE) here: https://go.dev/play/p/JwilhWMDl9k

Please save it locally as test-uint32-nan.go. go run test-uint32-nan.go on amd64 gives uint32(math.NaN()) returns 0 on amd64 (linux). just as in the Go Playground.

Test riscv64 either on native riscv64 machine, or on e.g. amd64 with QEMU installed with:

GOARCH=riscv64 go run test-uint32-nan.go

What did you expect to see?

$ GOARCH=riscv64 go run test-uint32-nan.go
uint32(math.NaN()) returns 0 on riscv64 (linux).

What did you see instead?

$ GOARCH=riscv64 go run test-uint32-nan.go
uint32(math.NaN()) returns 4294967295 on riscv64 (linux).

This difference of uint32(math.NaN()) output between riscv64 and other architectures results in:

It would be really nice if riscv64 could produce an identical result here, as it seems to be the only oddball out giving a different result.

Many thanks!
Happy New Year!

@anthonyfok anthonyfok changed the title uint32(math.NaN()) returns -1 on riscv64 (but 0 on all other architectures) uint32(math.NaN()) returns -1 on riscv64, but 0 on all other architectures Jan 1, 2024
@seankhliao seankhliao changed the title uint32(math.NaN()) returns -1 on riscv64, but 0 on all other architectures cmd/compile: uint32(math.NaN()) returns -1 on riscv64, but 0 on all other architectures Jan 1, 2024
@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jan 1, 2024
@seankhliao seankhliao added arch-riscv Issues solely affecting the riscv64 architecture. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Jan 1, 2024
@seankhliao
Copy link
Member

cc @golang/riscv64

@mauri870
Copy link
Member

mauri870 commented Jan 1, 2024

According to the spec

In all non-constant conversions involving floating-point or complex values, if the result type cannot represent the value the conversion succeeds but the result value is implementation-dependent.

My take on this is that you shouldn't be relying on the result of converting a NaN to any integer type, the result is implementation dependant, meaning it can change from one version of Go to another and sometimes between platforms.

Similar issue on wasm #35034

@anthonyfok
Copy link
Author

Thanks for the confirmation! I saw #35034 too, though seeing riscv64 is the only oddball out in that behaviour (and my primitive understanding assuming riscv64 would give the same result as ARM architectures...), and was wondering if the difference is due to RISC-V hardware or software implementation.

ECMAScript somehow has NaN, +Infinity and -Infinity all set to 0, but then Go isn't ECMAScript. I guess other languages are more like Go as in the result value is implementation-dependent.

Thanks again! Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-riscv Issues solely affecting the riscv64 architecture. compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants