Skip to content

Commit a9f1ea4

Browse files
author
Bryan C. Mills
committed
Revert "cmd/compile: don't allow NaNs in floating-point constant ops"
This reverts CL 213477. Reason for revert: tests are failing on linux-mips*-rtrk builders. Change-Id: I8168f7450890233f1bd7e53930b73693c26d4dc0 Reviewed-on: https://go-review.googlesource.com/c/go/+/220897 Run-TryBot: Bryan C. Mills <[email protected]> Reviewed-by: Keith Randall <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 58ba0f9 commit a9f1ea4

File tree

11 files changed

+26
-200
lines changed

11 files changed

+26
-200
lines changed

src/cmd/compile/internal/gc/float_test.go

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -483,66 +483,6 @@ func TestFloat32StoreToLoadConstantFold(t *testing.T) {
483483
}
484484
}
485485

486-
// Signaling NaN values as constants.
487-
const (
488-
snan32bits uint32 = 0x7f800001
489-
snan64bits uint64 = 0x7ff0000000000001
490-
)
491-
492-
// Signaling NaNs as variables.
493-
var snan32bitsVar uint32 = snan32bits
494-
var snan64bitsVar uint64 = snan64bits
495-
496-
func TestFloatSignalingNaN(t *testing.T) {
497-
// Make sure we generate a signaling NaN from a constant properly.
498-
// See issue 36400.
499-
f32 := math.Float32frombits(snan32bits)
500-
g32 := math.Float32frombits(snan32bitsVar)
501-
x32 := math.Float32bits(f32)
502-
y32 := math.Float32bits(g32)
503-
if x32 != y32 {
504-
t.Errorf("got %x, want %x (diff=%x)", x32, y32, x32^y32)
505-
}
506-
507-
f64 := math.Float64frombits(snan64bits)
508-
g64 := math.Float64frombits(snan64bitsVar)
509-
x64 := math.Float64bits(f64)
510-
y64 := math.Float64bits(g64)
511-
if x64 != y64 {
512-
t.Errorf("got %x, want %x (diff=%x)", x64, y64, x64^y64)
513-
}
514-
}
515-
516-
func TestFloatSignalingNaNConversion(t *testing.T) {
517-
// Test to make sure when we convert a signaling NaN, it converts to a quiet NaN.
518-
// See issue 36399.
519-
s32 := math.Float32frombits(snan32bitsVar)
520-
q64 := float64(s32)
521-
if math.Float64bits(q64)>>52&1 == 0 {
522-
t.Errorf("got signaling NaN, want quiet NaN")
523-
}
524-
s64 := math.Float64frombits(snan64bitsVar)
525-
q32 := float32(s64)
526-
if math.Float32bits(q32)>>22&1 == 0 {
527-
t.Errorf("got signaling NaN, want quiet NaN")
528-
}
529-
}
530-
531-
func TestFloatSignalingNaNConversionConst(t *testing.T) {
532-
// Test to make sure when we convert a signaling NaN, it converts to a quiet NaN.
533-
// See issue 36399 and 36400.
534-
s32 := math.Float32frombits(snan32bits)
535-
q64 := float64(s32)
536-
if math.Float64bits(q64)>>52&1 == 0 {
537-
t.Errorf("got signaling NaN, want quiet NaN")
538-
}
539-
s64 := math.Float64frombits(snan64bits)
540-
q32 := float32(s64)
541-
if math.Float32bits(q32)>>22&1 == 0 {
542-
t.Errorf("got signaling NaN, want quiet NaN")
543-
}
544-
}
545-
546486
var sinkFloat float64
547487

548488
func BenchmarkMul2(b *testing.B) {

src/cmd/compile/internal/ssa/check.go

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -141,23 +141,15 @@ func checkFunc(f *Func) {
141141
f.Fatalf("bad int32 AuxInt value for %v", v)
142142
}
143143
canHaveAuxInt = true
144-
case auxInt64:
144+
case auxInt64, auxFloat64:
145145
canHaveAuxInt = true
146146
case auxInt128:
147147
// AuxInt must be zero, so leave canHaveAuxInt set to false.
148148
case auxFloat32:
149149
canHaveAuxInt = true
150-
if math.IsNaN(v.AuxFloat()) {
151-
f.Fatalf("value %v has an AuxInt that encodes a NaN", v)
152-
}
153150
if !isExactFloat32(v.AuxFloat()) {
154151
f.Fatalf("value %v has an AuxInt value that is not an exact float32", v)
155152
}
156-
case auxFloat64:
157-
canHaveAuxInt = true
158-
if math.IsNaN(v.AuxFloat()) {
159-
f.Fatalf("value %v has an AuxInt that encodes a NaN", v)
160-
}
161153
case auxString, auxSym, auxTyp, auxArchSpecific:
162154
canHaveAux = true
163155
case auxSymOff, auxSymValAndOff, auxTypSize:

src/cmd/compile/internal/ssa/gen/PPC64.rules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878

7979
// Constant folding
8080
(FABS (FMOVDconst [x])) -> (FMOVDconst [auxFrom64F(math.Abs(auxTo64F(x)))])
81-
(FSQRT (FMOVDconst [x])) && auxTo64F(x) >= 0 -> (FMOVDconst [auxFrom64F(math.Sqrt(auxTo64F(x)))])
81+
(FSQRT (FMOVDconst [x])) -> (FMOVDconst [auxFrom64F(math.Sqrt(auxTo64F(x)))])
8282
(FFLOOR (FMOVDconst [x])) -> (FMOVDconst [auxFrom64F(math.Floor(auxTo64F(x)))])
8383
(FCEIL (FMOVDconst [x])) -> (FMOVDconst [auxFrom64F(math.Ceil(auxTo64F(x)))])
8484
(FTRUNC (FMOVDconst [x])) -> (FMOVDconst [auxFrom64F(math.Trunc(auxTo64F(x)))])

src/cmd/compile/internal/ssa/gen/Wasm.rules

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@
372372
(I64Or (I64Const [x]) (I64Const [y])) -> (I64Const [x | y])
373373
(I64Xor (I64Const [x]) (I64Const [y])) -> (I64Const [x ^ y])
374374
(F64Add (F64Const [x]) (F64Const [y])) -> (F64Const [auxFrom64F(auxTo64F(x) + auxTo64F(y))])
375-
(F64Mul (F64Const [x]) (F64Const [y])) && !math.IsNaN(auxTo64F(x) * auxTo64F(y)) -> (F64Const [auxFrom64F(auxTo64F(x) * auxTo64F(y))])
375+
(F64Mul (F64Const [x]) (F64Const [y])) -> (F64Const [auxFrom64F(auxTo64F(x) * auxTo64F(y))])
376376
(I64Eq (I64Const [x]) (I64Const [y])) && x == y -> (I64Const [1])
377377
(I64Eq (I64Const [x]) (I64Const [y])) && x != y -> (I64Const [0])
378378
(I64Ne (I64Const [x]) (I64Const [y])) && x == y -> (I64Const [0])
@@ -382,16 +382,15 @@
382382
(I64ShrU (I64Const [x]) (I64Const [y])) -> (I64Const [int64(uint64(x) >> uint64(y))])
383383
(I64ShrS (I64Const [x]) (I64Const [y])) -> (I64Const [x >> uint64(y)])
384384

385-
// TODO: declare these operations as commutative and get rid of these rules?
386-
(I64Add (I64Const [x]) y) && y.Op != OpWasmI64Const -> (I64Add y (I64Const [x]))
387-
(I64Mul (I64Const [x]) y) && y.Op != OpWasmI64Const -> (I64Mul y (I64Const [x]))
388-
(I64And (I64Const [x]) y) && y.Op != OpWasmI64Const -> (I64And y (I64Const [x]))
389-
(I64Or (I64Const [x]) y) && y.Op != OpWasmI64Const -> (I64Or y (I64Const [x]))
390-
(I64Xor (I64Const [x]) y) && y.Op != OpWasmI64Const -> (I64Xor y (I64Const [x]))
391-
(F64Add (F64Const [x]) y) && y.Op != OpWasmF64Const -> (F64Add y (F64Const [x]))
392-
(F64Mul (F64Const [x]) y) && y.Op != OpWasmF64Const -> (F64Mul y (F64Const [x]))
393-
(I64Eq (I64Const [x]) y) && y.Op != OpWasmI64Const -> (I64Eq y (I64Const [x]))
394-
(I64Ne (I64Const [x]) y) && y.Op != OpWasmI64Const -> (I64Ne y (I64Const [x]))
385+
(I64Add (I64Const [x]) y) -> (I64Add y (I64Const [x]))
386+
(I64Mul (I64Const [x]) y) -> (I64Mul y (I64Const [x]))
387+
(I64And (I64Const [x]) y) -> (I64And y (I64Const [x]))
388+
(I64Or (I64Const [x]) y) -> (I64Or y (I64Const [x]))
389+
(I64Xor (I64Const [x]) y) -> (I64Xor y (I64Const [x]))
390+
(F64Add (F64Const [x]) y) -> (F64Add y (F64Const [x]))
391+
(F64Mul (F64Const [x]) y) -> (F64Mul y (F64Const [x]))
392+
(I64Eq (I64Const [x]) y) -> (I64Eq y (I64Const [x]))
393+
(I64Ne (I64Const [x]) y) -> (I64Ne y (I64Const [x]))
395394

396395
(I64Eq x (I64Const [0])) -> (I64Eqz x)
397396
(I64Ne x (I64Const [0])) -> (I64Eqz (I64Eqz x))

src/cmd/compile/internal/ssa/gen/generic.rules

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@
118118
(Mul16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c*d))])
119119
(Mul32 (Const32 [c]) (Const32 [d])) -> (Const32 [int64(int32(c*d))])
120120
(Mul64 (Const64 [c]) (Const64 [d])) -> (Const64 [c*d])
121-
(Mul32F (Const32F [c]) (Const32F [d])) && !math.IsNaN(float64(auxTo32F(c) * auxTo32F(d))) -> (Const32F [auxFrom32F(auxTo32F(c) * auxTo32F(d))])
122-
(Mul64F (Const64F [c]) (Const64F [d])) && !math.IsNaN(auxTo64F(c) * auxTo64F(d)) -> (Const64F [auxFrom64F(auxTo64F(c) * auxTo64F(d))])
121+
(Mul32F (Const32F [c]) (Const32F [d])) -> (Const32F [auxFrom32F(auxTo32F(c) * auxTo32F(d))])
122+
(Mul64F (Const64F [c]) (Const64F [d])) -> (Const64F [auxFrom64F(auxTo64F(c) * auxTo64F(d))])
123123

124124
(And8 (Const8 [c]) (Const8 [d])) -> (Const8 [int64(int8(c&d))])
125125
(And16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c&d))])
@@ -144,8 +144,8 @@
144144
(Div16u (Const16 [c]) (Const16 [d])) && d != 0 -> (Const16 [int64(int16(uint16(c)/uint16(d)))])
145145
(Div32u (Const32 [c]) (Const32 [d])) && d != 0 -> (Const32 [int64(int32(uint32(c)/uint32(d)))])
146146
(Div64u (Const64 [c]) (Const64 [d])) && d != 0 -> (Const64 [int64(uint64(c)/uint64(d))])
147-
(Div32F (Const32F [c]) (Const32F [d])) && !math.IsNaN(float64(auxTo32F(c) / auxTo32F(d))) -> (Const32F [auxFrom32F(auxTo32F(c) / auxTo32F(d))])
148-
(Div64F (Const64F [c]) (Const64F [d])) && !math.IsNaN(auxTo64F(c) / auxTo64F(d)) -> (Const64F [auxFrom64F(auxTo64F(c) / auxTo64F(d))])
147+
(Div32F (Const32F [c]) (Const32F [d])) -> (Const32F [auxFrom32F(auxTo32F(c) / auxTo32F(d))])
148+
(Div64F (Const64F [c]) (Const64F [d])) -> (Const64F [auxFrom64F(auxTo64F(c) / auxTo64F(d))])
149149
(Select0 (Div128u (Const64 [0]) lo y)) -> (Div64u lo y)
150150
(Select1 (Div128u (Const64 [0]) lo y)) -> (Mod64u lo y)
151151

@@ -588,8 +588,8 @@
588588
-> x
589589

590590
// Pass constants through math.Float{32,64}bits and math.Float{32,64}frombits
591-
(Load <t1> p1 (Store {t2} p2 (Const64 [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 8 && is64BitFloat(t1) && !math.IsNaN(math.Float64frombits(uint64(x))) -> (Const64F [x])
592-
(Load <t1> p1 (Store {t2} p2 (Const32 [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 4 && is32BitFloat(t1) && !math.IsNaN(float64(math.Float32frombits(uint32(x)))) -> (Const32F [auxFrom32F(math.Float32frombits(uint32(x)))])
591+
(Load <t1> p1 (Store {t2} p2 (Const64 [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 8 && is64BitFloat(t1) -> (Const64F [x])
592+
(Load <t1> p1 (Store {t2} p2 (Const32 [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 4 && is32BitFloat(t1) -> (Const32F [auxFrom32F(math.Float32frombits(uint32(x)))])
593593
(Load <t1> p1 (Store {t2} p2 (Const64F [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 8 && is64BitInt(t1) -> (Const64 [x])
594594
(Load <t1> p1 (Store {t2} p2 (Const32F [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 4 && is32BitInt(t1) -> (Const32 [int64(int32(math.Float32bits(auxTo32F(x))))])
595595

@@ -1858,7 +1858,7 @@
18581858
(Div32F x (Const32F <t> [c])) && reciprocalExact32(auxTo32F(c)) -> (Mul32F x (Const32F <t> [auxFrom32F(1/auxTo32F(c))]))
18591859
(Div64F x (Const64F <t> [c])) && reciprocalExact64(auxTo64F(c)) -> (Mul64F x (Const64F <t> [auxFrom64F(1/auxTo64F(c))]))
18601860

1861-
(Sqrt (Const64F [c])) && !math.IsNaN(math.Sqrt(auxTo64F(c))) -> (Const64F [auxFrom64F(math.Sqrt(auxTo64F(c)))])
1861+
(Sqrt (Const64F [c])) -> (Const64F [auxFrom64F(math.Sqrt(auxTo64F(c)))])
18621862

18631863
// recognize runtime.newobject and don't Zero/Nilcheck it
18641864
(Zero (Load (OffPtr [c] (SP)) mem) mem)

src/cmd/compile/internal/ssa/gen/genericOps.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -339,12 +339,7 @@ var genericOps = []opData{
339339
{name: "Const32", aux: "Int32"}, // auxint is sign-extended 32 bits
340340
// Note: ConstX are sign-extended even when the type of the value is unsigned.
341341
// For instance, uint8(0xaa) is stored as auxint=0xffffffffffffffaa.
342-
{name: "Const64", aux: "Int64"}, // value is auxint
343-
// Note: for both Const32F and Const64F, we disallow encoding NaNs.
344-
// Signaling NaNs are tricky because if you do anything with them, they become quiet.
345-
// Particularly, converting a 32 bit sNaN to 64 bit and back converts it to a qNaN.
346-
// See issue 36399 and 36400.
347-
// Encodings of +inf, -inf, and -0 are fine.
342+
{name: "Const64", aux: "Int64"}, // value is auxint
348343
{name: "Const32F", aux: "Float32"}, // value is math.Float64frombits(uint64(auxint)) and is exactly representable as float 32
349344
{name: "Const64F", aux: "Float64"}, // value is math.Float64frombits(uint64(auxint))
350345
{name: "ConstInterface"}, // nil interface

src/cmd/compile/internal/ssa/rewrite.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -487,17 +487,11 @@ func DivisionNeedsFixUp(v *Value) bool {
487487

488488
// auxFrom64F encodes a float64 value so it can be stored in an AuxInt.
489489
func auxFrom64F(f float64) int64 {
490-
if f != f {
491-
panic("can't encode a NaN in AuxInt field")
492-
}
493490
return int64(math.Float64bits(f))
494491
}
495492

496493
// auxFrom32F encodes a float32 value so it can be stored in an AuxInt.
497494
func auxFrom32F(f float32) int64 {
498-
if f != f {
499-
panic("can't encode a NaN in AuxInt field")
500-
}
501495
return int64(math.Float64bits(extend32Fto64F(f)))
502496
}
503497

src/cmd/compile/internal/ssa/rewritePPC64.go

Lines changed: 0 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)