go: cmd/compile: it is not possible to prevent FMA with complex values
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="arm64" 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="0" 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 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build515689865=/tmp/go-build -gno-record-gcc-switches"
What did you do?
Examine the assembly generated for the code at https://play.golang.org/p/JuTC-BPAIJN with GOARCH=arm64
What did you expect to see?
No FMA/FMS instructions emitted.
What did you see instead?
0x00ac 00172 (/home/user/c.go:19) PCDATA ZR, $5
0x00ac 00172 (/home/user/c.go:19) FMOVD 8(R8), F4
0x00b0 00176 (/home/user/c.go:19) FMSUBD F1, F3, F4, F3
0x00b4 00180 (/home/user/c.go:19) SCVTFD R2, F5
0x00b8 00184 (/home/user/c.go:19) FADDD F5, F3, F3
0x00bc 00188 (/home/user/c.go:19) FMOVD F3, (R0)(R6)
0x00c0 00192 (/home/user/c.go:19) FMULD F4, F0, F0
0x00c4 00196 (/home/user/c.go:19) FMADDD F1, F0, F2, F0
0x00c8 00200 (/home/user/c.go:19) FMOVD ZR, F1
0x00cc 00204 (/home/user/c.go:19) FADDD F0, F1, F0
No amount of wrapping the operands in complex128
prevents this AFAICS.
About this issue
- Original URL
- State: open
- Created 4 years ago
- Comments: 16 (15 by maintainers)
The original issues that prompted this have been resolved, in part by changing the compiler to not emit fused operation instructions. The original issues covered the range of differences in precision causing changes in output precision, differences in precision changing gross behaviour and an actual real bug in our code (~50 issues were rolled up in the original problem).
Because of the complexity of the issues we had (and the number of sites where fused operations can be constructed), it would have been very helpful to be able to tell the compiler to not emit fused operation instructions in order to exclude that as a cause. I’ll note that discordance between precision at different sites has historically been a cause of catastrophic failures (I hope no-one is using Go for missile guidance).