Skip to content

cmd/compile: inconsistent float64 behaviour between arm64 and amd64 #36536

@kortschak

Description

@kortschak

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

$ go version
go version go1.13.6 linux/amd64

Does this issue reproduce with the latest release?

Yes.

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

go env Output
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN="/home/user/bin"
GOCACHE="/home/user/.cache/go-build"
GOENV="/home/user/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/user"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/user/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/user/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build254211515=/tmp/go-build -gno-record-gcc-switches"

What did you do?

~ $ cat inv.go 
package main

import "fmt"

func main() {
	nNeg := 10.0
	fpr := []float64{0, 10}
	invNeg := 1 / nNeg
	for i := range fpr {
		fpr[i] = 1 - fpr[i]*invNeg
	}
	fmt.Println(fpr)
}
~ $ cat div.go 
package main

import "fmt"

func main() {
	nNeg := 10.0
	fpr := []float64{0, 10}
	for i := range fpr {
		fpr[i] = 1 - fpr[i]/nNeg
	}
	fmt.Println(fpr)
}
~ $ GOARCH=amd64 go run inv.go 
[1 0]
~ $ GOARCH=amd64 go run div.go 
[1 0]
~ $ GOARCH=arm64 go run inv.go 
[1 -5.551115123125783e-17]
~ $ GOARCH=arm64 go run div.go 
[1 0]

inv.go: https://play.golang.org/p/yqox_9PRxI1
div.go: https://play.golang.org/p/8HhGeB-rUpn

Note that while this terminal session is all run on one machine using qemu-user for arm64, the same behaviour is seen on real arm64 hardware.

What did you expect to see?

Matching behaviour between arm64 and amd64.

What did you see instead?

Floating point difference for one approach.

This difference is only seen when the floats are in a slice, the equivalent in a single value behaves as expected.

~ $ cat inv_single.go 
package main

import "fmt"

func main() {
	nNeg := 10.0
	fpr := 10.0
	invNeg := 1 / nNeg
	fpr = 1 - fpr*invNeg
	fmt.Println(fpr)
}
~ $ GOARCH=amd64 go run inv_single.go 
0
~ $ GOARCH=arm64 go run inv_single.go 
0

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions