aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/check.go
diff options
context:
space:
mode:
authorMichael Munday <mike.munday@ibm.com>2018-09-03 12:14:31 +0100
committerMichael Munday <mike.munday@ibm.com>2018-09-05 15:27:15 +0000
commit48af3a8be593d349d7af8e831e26b5b2798a464e (patch)
tree8fcb5ffea0f752c56cd1fd343fe2954f1d64c37f /src/cmd/compile/internal/ssa/check.go
parent067dfce21f945646b9e6bf2a7559eaaecf40b4d6 (diff)
downloadgo-48af3a8be593d349d7af8e831e26b5b2798a464e.tar.gz
go-48af3a8be593d349d7af8e831e26b5b2798a464e.zip
cmd/compile: fix store-to-load forwarding of 32-bit sNaNs
Signalling NaNs were being converted to quiet NaNs during constant propagation through integer <-> float store-to-load forwarding. This occurs because we store float32 constants as float64 values and CPU hardware 'quietens' NaNs during conversion between the two. Eventually we want to move to using float32 values to store float32 constants, however this will be a big change since both the compiler and the assembler expect float64 values. So for now this is a small change that will fix the immediate issue. Fixes #27193. Change-Id: Iac54bd8c13abe26f9396712bc71f9b396f842724 Reviewed-on: https://go-review.googlesource.com/132956 Run-TryBot: Michael Munday <mike.munday@ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/ssa/check.go')
-rw-r--r--src/cmd/compile/internal/ssa/check.go15
1 files changed, 10 insertions, 5 deletions
diff --git a/src/cmd/compile/internal/ssa/check.go b/src/cmd/compile/internal/ssa/check.go
index 556e7fb7f7..13e8d7b3de 100644
--- a/src/cmd/compile/internal/ssa/check.go
+++ b/src/cmd/compile/internal/ssa/check.go
@@ -6,6 +6,7 @@ package ssa
import (
"math"
+ "math/bits"
)
// checkFunc checks invariants of f.
@@ -146,7 +147,7 @@ func checkFunc(f *Func) {
// AuxInt must be zero, so leave canHaveAuxInt set to false.
case auxFloat32:
canHaveAuxInt = true
- if !isExactFloat32(v) {
+ if !isExactFloat32(v.AuxFloat()) {
f.Fatalf("value %v has an AuxInt value that is not an exact float32", v)
}
case auxString, auxSym, auxTyp:
@@ -508,8 +509,12 @@ func domCheck(f *Func, sdom SparseTree, x, y *Block) bool {
return sdom.isAncestorEq(x, y)
}
-// isExactFloat32 reports whether v has an AuxInt that can be exactly represented as a float32.
-func isExactFloat32(v *Value) bool {
- x := v.AuxFloat()
- return math.Float64bits(x) == math.Float64bits(float64(float32(x)))
+// isExactFloat32 reports whether x can be exactly represented as a float32.
+func isExactFloat32(x float64) bool {
+ // Check the mantissa is in range.
+ if bits.TrailingZeros64(math.Float64bits(x)) < 52-23 {
+ return false
+ }
+ // Check the exponent is in range. The mantissa check above is sufficient for NaN values.
+ return math.IsNaN(x) || x == float64(float32(x))
}