diff options
author | Michael Munday <mike.munday@ibm.com> | 2018-09-03 12:14:31 +0100 |
---|---|---|
committer | Michael Munday <mike.munday@ibm.com> | 2018-09-05 15:27:15 +0000 |
commit | 48af3a8be593d349d7af8e831e26b5b2798a464e (patch) | |
tree | 8fcb5ffea0f752c56cd1fd343fe2954f1d64c37f /src/cmd/compile/internal/ssa/check.go | |
parent | 067dfce21f945646b9e6bf2a7559eaaecf40b4d6 (diff) | |
download | go-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.go | 15 |
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)) } |