aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/check.go
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2020-03-03 17:56:20 +0000
committerKeith Randall <khr@golang.org>2020-03-04 04:49:54 +0000
commitcd9fd640db419ec81026945eb4f22bfe5ff5a27f (patch)
tree57da099235cea00c6f1be4b756bf00204b94ca65 /src/cmd/compile/internal/ssa/check.go
parent24343cb88640ae1e7dbfc4ec2f3ae81fc0aa07c7 (diff)
downloadgo-cd9fd640db419ec81026945eb4f22bfe5ff5a27f.tar.gz
go-cd9fd640db419ec81026945eb4f22bfe5ff5a27f.zip
cmd/compile: don't allow NaNs in floating-point constant ops
Trying this CL again, with a fixed test that allows platforms to disagree on the exact behavior of converting NaNs. We store 32-bit floating point constants in a 64-bit field, by converting that 32-bit float to 64-bit float to store it, and convert it back to use it. That works for *almost* all floating-point constants. The exception is signaling NaNs. The round trip described above means we can't represent a 32-bit signaling NaN, because conversions strip the signaling bit. To fix this issue, just forbid NaNs as floating-point constants in SSA form. This shouldn't affect any real-world code, as people seldom constant-propagate NaNs (except in test code). Additionally, NaNs are somewhat underspecified (which of the many NaNs do you get when dividing 0/0?), so when cross-compiling there's a danger of using the compiler machine's NaN regime for some math, and the target machine's NaN regime for other math. Better to use the target machine's NaN regime always. Update #36400 Change-Id: Idf203b688a15abceabbd66ba290d4e9f63619ecb Reviewed-on: https://go-review.googlesource.com/c/go/+/221790 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/check.go')
-rw-r--r--src/cmd/compile/internal/ssa/check.go10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/ssa/check.go b/src/cmd/compile/internal/ssa/check.go
index a6746805f7..4c694a03ac 100644
--- a/src/cmd/compile/internal/ssa/check.go
+++ b/src/cmd/compile/internal/ssa/check.go
@@ -141,15 +141,23 @@ func checkFunc(f *Func) {
f.Fatalf("bad int32 AuxInt value for %v", v)
}
canHaveAuxInt = true
- case auxInt64, auxFloat64, auxARM64BitField:
+ case auxInt64, auxARM64BitField:
canHaveAuxInt = true
case auxInt128:
// AuxInt must be zero, so leave canHaveAuxInt set to false.
case auxFloat32:
canHaveAuxInt = true
+ if math.IsNaN(v.AuxFloat()) {
+ f.Fatalf("value %v has an AuxInt that encodes a NaN", v)
+ }
if !isExactFloat32(v.AuxFloat()) {
f.Fatalf("value %v has an AuxInt value that is not an exact float32", v)
}
+ case auxFloat64:
+ canHaveAuxInt = true
+ if math.IsNaN(v.AuxFloat()) {
+ f.Fatalf("value %v has an AuxInt that encodes a NaN", v)
+ }
case auxString, auxSym, auxTyp, auxArchSpecific:
canHaveAux = true
case auxSymOff, auxSymValAndOff, auxTypSize: