From: Bryan C. Mills Date: Tue, 25 Feb 2020 14:36:38 +0000 (+0000) Subject: Revert "cmd/compile: don't allow NaNs in floating-point constant ops" X-Git-Tag: go1.15beta1~1073 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=a9f1ea4a83da919acc254107661b99d0d6f8c7ec;p=gostls13.git 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 Reviewed-by: Keith Randall TryBot-Result: Gobot Gobot --- diff --git a/src/cmd/compile/internal/gc/float_test.go b/src/cmd/compile/internal/gc/float_test.go index 94da49ee41..c5c604003a 100644 --- a/src/cmd/compile/internal/gc/float_test.go +++ b/src/cmd/compile/internal/gc/float_test.go @@ -483,66 +483,6 @@ func TestFloat32StoreToLoadConstantFold(t *testing.T) { } } -// Signaling NaN values as constants. -const ( - snan32bits uint32 = 0x7f800001 - snan64bits uint64 = 0x7ff0000000000001 -) - -// Signaling NaNs as variables. -var snan32bitsVar uint32 = snan32bits -var snan64bitsVar uint64 = snan64bits - -func TestFloatSignalingNaN(t *testing.T) { - // Make sure we generate a signaling NaN from a constant properly. - // See issue 36400. - f32 := math.Float32frombits(snan32bits) - g32 := math.Float32frombits(snan32bitsVar) - x32 := math.Float32bits(f32) - y32 := math.Float32bits(g32) - if x32 != y32 { - t.Errorf("got %x, want %x (diff=%x)", x32, y32, x32^y32) - } - - f64 := math.Float64frombits(snan64bits) - g64 := math.Float64frombits(snan64bitsVar) - x64 := math.Float64bits(f64) - y64 := math.Float64bits(g64) - if x64 != y64 { - t.Errorf("got %x, want %x (diff=%x)", x64, y64, x64^y64) - } -} - -func TestFloatSignalingNaNConversion(t *testing.T) { - // Test to make sure when we convert a signaling NaN, it converts to a quiet NaN. - // See issue 36399. - s32 := math.Float32frombits(snan32bitsVar) - q64 := float64(s32) - if math.Float64bits(q64)>>52&1 == 0 { - t.Errorf("got signaling NaN, want quiet NaN") - } - s64 := math.Float64frombits(snan64bitsVar) - q32 := float32(s64) - if math.Float32bits(q32)>>22&1 == 0 { - t.Errorf("got signaling NaN, want quiet NaN") - } -} - -func TestFloatSignalingNaNConversionConst(t *testing.T) { - // Test to make sure when we convert a signaling NaN, it converts to a quiet NaN. - // See issue 36399 and 36400. - s32 := math.Float32frombits(snan32bits) - q64 := float64(s32) - if math.Float64bits(q64)>>52&1 == 0 { - t.Errorf("got signaling NaN, want quiet NaN") - } - s64 := math.Float64frombits(snan64bits) - q32 := float32(s64) - if math.Float32bits(q32)>>22&1 == 0 { - t.Errorf("got signaling NaN, want quiet NaN") - } -} - var sinkFloat float64 func BenchmarkMul2(b *testing.B) { diff --git a/src/cmd/compile/internal/ssa/check.go b/src/cmd/compile/internal/ssa/check.go index ecce581f4b..4e258fe82b 100644 --- a/src/cmd/compile/internal/ssa/check.go +++ b/src/cmd/compile/internal/ssa/check.go @@ -141,23 +141,15 @@ func checkFunc(f *Func) { f.Fatalf("bad int32 AuxInt value for %v", v) } canHaveAuxInt = true - case auxInt64: + case auxInt64, auxFloat64: 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: diff --git a/src/cmd/compile/internal/ssa/gen/PPC64.rules b/src/cmd/compile/internal/ssa/gen/PPC64.rules index ed95620db4..e03712b118 100644 --- a/src/cmd/compile/internal/ssa/gen/PPC64.rules +++ b/src/cmd/compile/internal/ssa/gen/PPC64.rules @@ -78,7 +78,7 @@ // Constant folding (FABS (FMOVDconst [x])) -> (FMOVDconst [auxFrom64F(math.Abs(auxTo64F(x)))]) -(FSQRT (FMOVDconst [x])) && auxTo64F(x) >= 0 -> (FMOVDconst [auxFrom64F(math.Sqrt(auxTo64F(x)))]) +(FSQRT (FMOVDconst [x])) -> (FMOVDconst [auxFrom64F(math.Sqrt(auxTo64F(x)))]) (FFLOOR (FMOVDconst [x])) -> (FMOVDconst [auxFrom64F(math.Floor(auxTo64F(x)))]) (FCEIL (FMOVDconst [x])) -> (FMOVDconst [auxFrom64F(math.Ceil(auxTo64F(x)))]) (FTRUNC (FMOVDconst [x])) -> (FMOVDconst [auxFrom64F(math.Trunc(auxTo64F(x)))]) diff --git a/src/cmd/compile/internal/ssa/gen/Wasm.rules b/src/cmd/compile/internal/ssa/gen/Wasm.rules index 68d26f8268..1080f0d820 100644 --- a/src/cmd/compile/internal/ssa/gen/Wasm.rules +++ b/src/cmd/compile/internal/ssa/gen/Wasm.rules @@ -372,7 +372,7 @@ (I64Or (I64Const [x]) (I64Const [y])) -> (I64Const [x | y]) (I64Xor (I64Const [x]) (I64Const [y])) -> (I64Const [x ^ y]) (F64Add (F64Const [x]) (F64Const [y])) -> (F64Const [auxFrom64F(auxTo64F(x) + auxTo64F(y))]) -(F64Mul (F64Const [x]) (F64Const [y])) && !math.IsNaN(auxTo64F(x) * auxTo64F(y)) -> (F64Const [auxFrom64F(auxTo64F(x) * auxTo64F(y))]) +(F64Mul (F64Const [x]) (F64Const [y])) -> (F64Const [auxFrom64F(auxTo64F(x) * auxTo64F(y))]) (I64Eq (I64Const [x]) (I64Const [y])) && x == y -> (I64Const [1]) (I64Eq (I64Const [x]) (I64Const [y])) && x != y -> (I64Const [0]) (I64Ne (I64Const [x]) (I64Const [y])) && x == y -> (I64Const [0]) @@ -382,16 +382,15 @@ (I64ShrU (I64Const [x]) (I64Const [y])) -> (I64Const [int64(uint64(x) >> uint64(y))]) (I64ShrS (I64Const [x]) (I64Const [y])) -> (I64Const [x >> uint64(y)]) -// TODO: declare these operations as commutative and get rid of these rules? -(I64Add (I64Const [x]) y) && y.Op != OpWasmI64Const -> (I64Add y (I64Const [x])) -(I64Mul (I64Const [x]) y) && y.Op != OpWasmI64Const -> (I64Mul y (I64Const [x])) -(I64And (I64Const [x]) y) && y.Op != OpWasmI64Const -> (I64And y (I64Const [x])) -(I64Or (I64Const [x]) y) && y.Op != OpWasmI64Const -> (I64Or y (I64Const [x])) -(I64Xor (I64Const [x]) y) && y.Op != OpWasmI64Const -> (I64Xor y (I64Const [x])) -(F64Add (F64Const [x]) y) && y.Op != OpWasmF64Const -> (F64Add y (F64Const [x])) -(F64Mul (F64Const [x]) y) && y.Op != OpWasmF64Const -> (F64Mul y (F64Const [x])) -(I64Eq (I64Const [x]) y) && y.Op != OpWasmI64Const -> (I64Eq y (I64Const [x])) -(I64Ne (I64Const [x]) y) && y.Op != OpWasmI64Const -> (I64Ne y (I64Const [x])) +(I64Add (I64Const [x]) y) -> (I64Add y (I64Const [x])) +(I64Mul (I64Const [x]) y) -> (I64Mul y (I64Const [x])) +(I64And (I64Const [x]) y) -> (I64And y (I64Const [x])) +(I64Or (I64Const [x]) y) -> (I64Or y (I64Const [x])) +(I64Xor (I64Const [x]) y) -> (I64Xor y (I64Const [x])) +(F64Add (F64Const [x]) y) -> (F64Add y (F64Const [x])) +(F64Mul (F64Const [x]) y) -> (F64Mul y (F64Const [x])) +(I64Eq (I64Const [x]) y) -> (I64Eq y (I64Const [x])) +(I64Ne (I64Const [x]) y) -> (I64Ne y (I64Const [x])) (I64Eq x (I64Const [0])) -> (I64Eqz x) (I64Ne x (I64Const [0])) -> (I64Eqz (I64Eqz x)) diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules index 8e51b6b657..1382cdc259 100644 --- a/src/cmd/compile/internal/ssa/gen/generic.rules +++ b/src/cmd/compile/internal/ssa/gen/generic.rules @@ -118,8 +118,8 @@ (Mul16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c*d))]) (Mul32 (Const32 [c]) (Const32 [d])) -> (Const32 [int64(int32(c*d))]) (Mul64 (Const64 [c]) (Const64 [d])) -> (Const64 [c*d]) -(Mul32F (Const32F [c]) (Const32F [d])) && !math.IsNaN(float64(auxTo32F(c) * auxTo32F(d))) -> (Const32F [auxFrom32F(auxTo32F(c) * auxTo32F(d))]) -(Mul64F (Const64F [c]) (Const64F [d])) && !math.IsNaN(auxTo64F(c) * auxTo64F(d)) -> (Const64F [auxFrom64F(auxTo64F(c) * auxTo64F(d))]) +(Mul32F (Const32F [c]) (Const32F [d])) -> (Const32F [auxFrom32F(auxTo32F(c) * auxTo32F(d))]) +(Mul64F (Const64F [c]) (Const64F [d])) -> (Const64F [auxFrom64F(auxTo64F(c) * auxTo64F(d))]) (And8 (Const8 [c]) (Const8 [d])) -> (Const8 [int64(int8(c&d))]) (And16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c&d))]) @@ -144,8 +144,8 @@ (Div16u (Const16 [c]) (Const16 [d])) && d != 0 -> (Const16 [int64(int16(uint16(c)/uint16(d)))]) (Div32u (Const32 [c]) (Const32 [d])) && d != 0 -> (Const32 [int64(int32(uint32(c)/uint32(d)))]) (Div64u (Const64 [c]) (Const64 [d])) && d != 0 -> (Const64 [int64(uint64(c)/uint64(d))]) -(Div32F (Const32F [c]) (Const32F [d])) && !math.IsNaN(float64(auxTo32F(c) / auxTo32F(d))) -> (Const32F [auxFrom32F(auxTo32F(c) / auxTo32F(d))]) -(Div64F (Const64F [c]) (Const64F [d])) && !math.IsNaN(auxTo64F(c) / auxTo64F(d)) -> (Const64F [auxFrom64F(auxTo64F(c) / auxTo64F(d))]) +(Div32F (Const32F [c]) (Const32F [d])) -> (Const32F [auxFrom32F(auxTo32F(c) / auxTo32F(d))]) +(Div64F (Const64F [c]) (Const64F [d])) -> (Const64F [auxFrom64F(auxTo64F(c) / auxTo64F(d))]) (Select0 (Div128u (Const64 [0]) lo y)) -> (Div64u lo y) (Select1 (Div128u (Const64 [0]) lo y)) -> (Mod64u lo y) @@ -588,8 +588,8 @@ -> x // Pass constants through math.Float{32,64}bits and math.Float{32,64}frombits - (Load p1 (Store {t2} p2 (Const64 [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 8 && is64BitFloat(t1) && !math.IsNaN(math.Float64frombits(uint64(x))) -> (Const64F [x]) - (Load 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)))]) +(Load p1 (Store {t2} p2 (Const64 [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 8 && is64BitFloat(t1) -> (Const64F [x]) +(Load p1 (Store {t2} p2 (Const32 [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 4 && is32BitFloat(t1) -> (Const32F [auxFrom32F(math.Float32frombits(uint32(x)))]) (Load p1 (Store {t2} p2 (Const64F [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 8 && is64BitInt(t1) -> (Const64 [x]) (Load p1 (Store {t2} p2 (Const32F [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 4 && is32BitInt(t1) -> (Const32 [int64(int32(math.Float32bits(auxTo32F(x))))]) @@ -1858,7 +1858,7 @@ (Div32F x (Const32F [c])) && reciprocalExact32(auxTo32F(c)) -> (Mul32F x (Const32F [auxFrom32F(1/auxTo32F(c))])) (Div64F x (Const64F [c])) && reciprocalExact64(auxTo64F(c)) -> (Mul64F x (Const64F [auxFrom64F(1/auxTo64F(c))])) -(Sqrt (Const64F [c])) && !math.IsNaN(math.Sqrt(auxTo64F(c))) -> (Const64F [auxFrom64F(math.Sqrt(auxTo64F(c)))]) +(Sqrt (Const64F [c])) -> (Const64F [auxFrom64F(math.Sqrt(auxTo64F(c)))]) // recognize runtime.newobject and don't Zero/Nilcheck it (Zero (Load (OffPtr [c] (SP)) mem) mem) diff --git a/src/cmd/compile/internal/ssa/gen/genericOps.go b/src/cmd/compile/internal/ssa/gen/genericOps.go index cc72c76c2d..b638d98887 100644 --- a/src/cmd/compile/internal/ssa/gen/genericOps.go +++ b/src/cmd/compile/internal/ssa/gen/genericOps.go @@ -339,12 +339,7 @@ var genericOps = []opData{ {name: "Const32", aux: "Int32"}, // auxint is sign-extended 32 bits // Note: ConstX are sign-extended even when the type of the value is unsigned. // For instance, uint8(0xaa) is stored as auxint=0xffffffffffffffaa. - {name: "Const64", aux: "Int64"}, // value is auxint - // Note: for both Const32F and Const64F, we disallow encoding NaNs. - // Signaling NaNs are tricky because if you do anything with them, they become quiet. - // Particularly, converting a 32 bit sNaN to 64 bit and back converts it to a qNaN. - // See issue 36399 and 36400. - // Encodings of +inf, -inf, and -0 are fine. + {name: "Const64", aux: "Int64"}, // value is auxint {name: "Const32F", aux: "Float32"}, // value is math.Float64frombits(uint64(auxint)) and is exactly representable as float 32 {name: "Const64F", aux: "Float64"}, // value is math.Float64frombits(uint64(auxint)) {name: "ConstInterface"}, // nil interface diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go index 61c5a6bff8..ef24dad747 100644 --- a/src/cmd/compile/internal/ssa/rewrite.go +++ b/src/cmd/compile/internal/ssa/rewrite.go @@ -487,17 +487,11 @@ func DivisionNeedsFixUp(v *Value) bool { // auxFrom64F encodes a float64 value so it can be stored in an AuxInt. func auxFrom64F(f float64) int64 { - if f != f { - panic("can't encode a NaN in AuxInt field") - } return int64(math.Float64bits(f)) } // auxFrom32F encodes a float32 value so it can be stored in an AuxInt. func auxFrom32F(f float32) int64 { - if f != f { - panic("can't encode a NaN in AuxInt field") - } return int64(math.Float64bits(extend32Fto64F(f))) } diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go index 6009b74588..9f62e0d3ba 100644 --- a/src/cmd/compile/internal/ssa/rewritePPC64.go +++ b/src/cmd/compile/internal/ssa/rewritePPC64.go @@ -5828,16 +5828,12 @@ func rewriteValuePPC64_OpPPC64FNEG(v *Value) bool { func rewriteValuePPC64_OpPPC64FSQRT(v *Value) bool { v_0 := v.Args[0] // match: (FSQRT (FMOVDconst [x])) - // cond: auxTo64F(x) >= 0 // result: (FMOVDconst [auxFrom64F(math.Sqrt(auxTo64F(x)))]) for { if v_0.Op != OpPPC64FMOVDconst { break } x := v_0.AuxInt - if !(auxTo64F(x) >= 0) { - break - } v.reset(OpPPC64FMOVDconst) v.AuxInt = auxFrom64F(math.Sqrt(auxTo64F(x))) return true diff --git a/src/cmd/compile/internal/ssa/rewriteWasm.go b/src/cmd/compile/internal/ssa/rewriteWasm.go index d3fc82b86b..9e236a6e0e 100644 --- a/src/cmd/compile/internal/ssa/rewriteWasm.go +++ b/src/cmd/compile/internal/ssa/rewriteWasm.go @@ -3,7 +3,6 @@ package ssa -import "math" import "cmd/internal/objabi" import "cmd/compile/internal/types" @@ -3994,7 +3993,6 @@ func rewriteValueWasm_OpWasmF64Add(v *Value) bool { return true } // match: (F64Add (F64Const [x]) y) - // cond: y.Op != OpWasmF64Const // result: (F64Add y (F64Const [x])) for { if v_0.Op != OpWasmF64Const { @@ -4002,9 +4000,6 @@ func rewriteValueWasm_OpWasmF64Add(v *Value) bool { } x := v_0.AuxInt y := v_1 - if !(y.Op != OpWasmF64Const) { - break - } v.reset(OpWasmF64Add) v.AddArg(y) v0 := b.NewValue0(v.Pos, OpWasmF64Const, typ.Float64) @@ -4020,7 +4015,6 @@ func rewriteValueWasm_OpWasmF64Mul(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (F64Mul (F64Const [x]) (F64Const [y])) - // cond: !math.IsNaN(auxTo64F(x) * auxTo64F(y)) // result: (F64Const [auxFrom64F(auxTo64F(x) * auxTo64F(y))]) for { if v_0.Op != OpWasmF64Const { @@ -4031,15 +4025,11 @@ func rewriteValueWasm_OpWasmF64Mul(v *Value) bool { break } y := v_1.AuxInt - if !(!math.IsNaN(auxTo64F(x) * auxTo64F(y))) { - break - } v.reset(OpWasmF64Const) v.AuxInt = auxFrom64F(auxTo64F(x) * auxTo64F(y)) return true } // match: (F64Mul (F64Const [x]) y) - // cond: y.Op != OpWasmF64Const // result: (F64Mul y (F64Const [x])) for { if v_0.Op != OpWasmF64Const { @@ -4047,9 +4037,6 @@ func rewriteValueWasm_OpWasmF64Mul(v *Value) bool { } x := v_0.AuxInt y := v_1 - if !(y.Op != OpWasmF64Const) { - break - } v.reset(OpWasmF64Mul) v.AddArg(y) v0 := b.NewValue0(v.Pos, OpWasmF64Const, typ.Float64) @@ -4080,7 +4067,6 @@ func rewriteValueWasm_OpWasmI64Add(v *Value) bool { return true } // match: (I64Add (I64Const [x]) y) - // cond: y.Op != OpWasmI64Const // result: (I64Add y (I64Const [x])) for { if v_0.Op != OpWasmI64Const { @@ -4088,9 +4074,6 @@ func rewriteValueWasm_OpWasmI64Add(v *Value) bool { } x := v_0.AuxInt y := v_1 - if !(y.Op != OpWasmI64Const) { - break - } v.reset(OpWasmI64Add) v.AddArg(y) v0 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64) @@ -4170,7 +4153,6 @@ func rewriteValueWasm_OpWasmI64And(v *Value) bool { return true } // match: (I64And (I64Const [x]) y) - // cond: y.Op != OpWasmI64Const // result: (I64And y (I64Const [x])) for { if v_0.Op != OpWasmI64Const { @@ -4178,9 +4160,6 @@ func rewriteValueWasm_OpWasmI64And(v *Value) bool { } x := v_0.AuxInt y := v_1 - if !(y.Op != OpWasmI64Const) { - break - } v.reset(OpWasmI64And) v.AddArg(y) v0 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64) @@ -4234,7 +4213,6 @@ func rewriteValueWasm_OpWasmI64Eq(v *Value) bool { return true } // match: (I64Eq (I64Const [x]) y) - // cond: y.Op != OpWasmI64Const // result: (I64Eq y (I64Const [x])) for { if v_0.Op != OpWasmI64Const { @@ -4242,9 +4220,6 @@ func rewriteValueWasm_OpWasmI64Eq(v *Value) bool { } x := v_0.AuxInt y := v_1 - if !(y.Op != OpWasmI64Const) { - break - } v.reset(OpWasmI64Eq) v.AddArg(y) v0 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64) @@ -4558,7 +4533,6 @@ func rewriteValueWasm_OpWasmI64Mul(v *Value) bool { return true } // match: (I64Mul (I64Const [x]) y) - // cond: y.Op != OpWasmI64Const // result: (I64Mul y (I64Const [x])) for { if v_0.Op != OpWasmI64Const { @@ -4566,9 +4540,6 @@ func rewriteValueWasm_OpWasmI64Mul(v *Value) bool { } x := v_0.AuxInt y := v_1 - if !(y.Op != OpWasmI64Const) { - break - } v.reset(OpWasmI64Mul) v.AddArg(y) v0 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64) @@ -4622,7 +4593,6 @@ func rewriteValueWasm_OpWasmI64Ne(v *Value) bool { return true } // match: (I64Ne (I64Const [x]) y) - // cond: y.Op != OpWasmI64Const // result: (I64Ne y (I64Const [x])) for { if v_0.Op != OpWasmI64Const { @@ -4630,9 +4600,6 @@ func rewriteValueWasm_OpWasmI64Ne(v *Value) bool { } x := v_0.AuxInt y := v_1 - if !(y.Op != OpWasmI64Const) { - break - } v.reset(OpWasmI64Ne) v.AddArg(y) v0 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64) @@ -4676,7 +4643,6 @@ func rewriteValueWasm_OpWasmI64Or(v *Value) bool { return true } // match: (I64Or (I64Const [x]) y) - // cond: y.Op != OpWasmI64Const // result: (I64Or y (I64Const [x])) for { if v_0.Op != OpWasmI64Const { @@ -4684,9 +4650,6 @@ func rewriteValueWasm_OpWasmI64Or(v *Value) bool { } x := v_0.AuxInt y := v_1 - if !(y.Op != OpWasmI64Const) { - break - } v.reset(OpWasmI64Or) v.AddArg(y) v0 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64) @@ -4889,7 +4852,6 @@ func rewriteValueWasm_OpWasmI64Xor(v *Value) bool { return true } // match: (I64Xor (I64Const [x]) y) - // cond: y.Op != OpWasmI64Const // result: (I64Xor y (I64Const [x])) for { if v_0.Op != OpWasmI64Const { @@ -4897,9 +4859,6 @@ func rewriteValueWasm_OpWasmI64Xor(v *Value) bool { } x := v_0.AuxInt y := v_1 - if !(y.Op != OpWasmI64Const) { - break - } v.reset(OpWasmI64Xor) v.AddArg(y) v0 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64) diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go index 1a40d3a699..a4a2506d8e 100644 --- a/src/cmd/compile/internal/ssa/rewritegeneric.go +++ b/src/cmd/compile/internal/ssa/rewritegeneric.go @@ -3579,7 +3579,6 @@ func rewriteValuegeneric_OpDiv32F(v *Value) bool { v_0 := v.Args[0] b := v.Block // match: (Div32F (Const32F [c]) (Const32F [d])) - // cond: !math.IsNaN(float64(auxTo32F(c) / auxTo32F(d))) // result: (Const32F [auxFrom32F(auxTo32F(c) / auxTo32F(d))]) for { if v_0.Op != OpConst32F { @@ -3590,9 +3589,6 @@ func rewriteValuegeneric_OpDiv32F(v *Value) bool { break } d := v_1.AuxInt - if !(!math.IsNaN(float64(auxTo32F(c) / auxTo32F(d)))) { - break - } v.reset(OpConst32F) v.AuxInt = auxFrom32F(auxTo32F(c) / auxTo32F(d)) return true @@ -4056,7 +4052,6 @@ func rewriteValuegeneric_OpDiv64F(v *Value) bool { v_0 := v.Args[0] b := v.Block // match: (Div64F (Const64F [c]) (Const64F [d])) - // cond: !math.IsNaN(auxTo64F(c) / auxTo64F(d)) // result: (Const64F [auxFrom64F(auxTo64F(c) / auxTo64F(d))]) for { if v_0.Op != OpConst64F { @@ -4067,9 +4062,6 @@ func rewriteValuegeneric_OpDiv64F(v *Value) bool { break } d := v_1.AuxInt - if !(!math.IsNaN(auxTo64F(c) / auxTo64F(d))) { - break - } v.reset(OpConst64F) v.AuxInt = auxFrom64F(auxTo64F(c) / auxTo64F(d)) return true @@ -9572,7 +9564,7 @@ func rewriteValuegeneric_OpLoad(v *Value) bool { return true } // match: (Load p1 (Store {t2} p2 (Const64 [x]) _)) - // cond: isSamePtr(p1,p2) && sizeof(t2) == 8 && is64BitFloat(t1) && !math.IsNaN(math.Float64frombits(uint64(x))) + // cond: isSamePtr(p1,p2) && sizeof(t2) == 8 && is64BitFloat(t1) // result: (Const64F [x]) for { t1 := v.Type @@ -9588,7 +9580,7 @@ func rewriteValuegeneric_OpLoad(v *Value) bool { break } x := v_1_1.AuxInt - if !(isSamePtr(p1, p2) && sizeof(t2) == 8 && is64BitFloat(t1) && !math.IsNaN(math.Float64frombits(uint64(x)))) { + if !(isSamePtr(p1, p2) && sizeof(t2) == 8 && is64BitFloat(t1)) { break } v.reset(OpConst64F) @@ -9596,7 +9588,7 @@ func rewriteValuegeneric_OpLoad(v *Value) bool { return true } // match: (Load p1 (Store {t2} p2 (Const32 [x]) _)) - // cond: isSamePtr(p1,p2) && sizeof(t2) == 4 && is32BitFloat(t1) && !math.IsNaN(float64(math.Float32frombits(uint32(x)))) + // cond: isSamePtr(p1,p2) && sizeof(t2) == 4 && is32BitFloat(t1) // result: (Const32F [auxFrom32F(math.Float32frombits(uint32(x)))]) for { t1 := v.Type @@ -9612,7 +9604,7 @@ func rewriteValuegeneric_OpLoad(v *Value) bool { break } x := v_1_1.AuxInt - if !(isSamePtr(p1, p2) && sizeof(t2) == 4 && is32BitFloat(t1) && !math.IsNaN(float64(math.Float32frombits(uint32(x))))) { + if !(isSamePtr(p1, p2) && sizeof(t2) == 4 && is32BitFloat(t1)) { break } v.reset(OpConst32F) @@ -13537,7 +13529,6 @@ func rewriteValuegeneric_OpMul32F(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (Mul32F (Const32F [c]) (Const32F [d])) - // cond: !math.IsNaN(float64(auxTo32F(c) * auxTo32F(d))) // result: (Const32F [auxFrom32F(auxTo32F(c) * auxTo32F(d))]) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { @@ -13549,9 +13540,6 @@ func rewriteValuegeneric_OpMul32F(v *Value) bool { continue } d := v_1.AuxInt - if !(!math.IsNaN(float64(auxTo32F(c) * auxTo32F(d)))) { - continue - } v.reset(OpConst32F) v.AuxInt = auxFrom32F(auxTo32F(c) * auxTo32F(d)) return true @@ -13791,7 +13779,6 @@ func rewriteValuegeneric_OpMul64F(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (Mul64F (Const64F [c]) (Const64F [d])) - // cond: !math.IsNaN(auxTo64F(c) * auxTo64F(d)) // result: (Const64F [auxFrom64F(auxTo64F(c) * auxTo64F(d))]) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { @@ -13803,9 +13790,6 @@ func rewriteValuegeneric_OpMul64F(v *Value) bool { continue } d := v_1.AuxInt - if !(!math.IsNaN(auxTo64F(c) * auxTo64F(d))) { - continue - } v.reset(OpConst64F) v.AuxInt = auxFrom64F(auxTo64F(c) * auxTo64F(d)) return true @@ -19679,16 +19663,12 @@ func rewriteValuegeneric_OpSlicemask(v *Value) bool { func rewriteValuegeneric_OpSqrt(v *Value) bool { v_0 := v.Args[0] // match: (Sqrt (Const64F [c])) - // cond: !math.IsNaN(math.Sqrt(auxTo64F(c))) // result: (Const64F [auxFrom64F(math.Sqrt(auxTo64F(c)))]) for { if v_0.Op != OpConst64F { break } c := v_0.AuxInt - if !(!math.IsNaN(math.Sqrt(auxTo64F(c)))) { - break - } v.reset(OpConst64F) v.AuxInt = auxFrom64F(math.Sqrt(auxTo64F(c))) return true diff --git a/test/codegen/math.go b/test/codegen/math.go index 1ebfda0405..80e5d60d96 100644 --- a/test/codegen/math.go +++ b/test/codegen/math.go @@ -151,13 +151,13 @@ func toFloat32(u32 uint32) float32 { func constantCheck64() bool { // amd64:"MOVB\t[$]0",-"FCMP",-"MOVB\t[$]1" // s390x:"MOV(B|BZ|D)\t[$]0,",-"FCMPU",-"MOV(B|BZ|D)\t[$]1," - return 0.5 == float64(uint32(1)) || 1.5 > float64(uint64(1<<63)) + return 0.5 == float64(uint32(1)) || 1.5 > float64(uint64(1<<63)) || math.NaN() == math.NaN() } func constantCheck32() bool { // amd64:"MOVB\t[$]1",-"FCMP",-"MOVB\t[$]0" // s390x:"MOV(B|BZ|D)\t[$]1,",-"FCMPU",-"MOV(B|BZ|D)\t[$]0," - return float32(0.5) <= float32(int64(1)) && float32(1.5) >= float32(int32(-1<<31)) + return float32(0.5) <= float32(int64(1)) && float32(1.5) >= float32(int32(-1<<31)) && float32(math.NaN()) != float32(math.NaN()) } // Test that integer constants are converted to floating point constants @@ -186,32 +186,3 @@ func constantConvertInt32(x uint32) uint32 { } return x } - -func nanGenerate64() float64 { - // Test to make sure we don't generate a NaN while constant propagating. - // See issue 36400. - zero := 0.0 - // amd64:-"DIVSD" - inf := 1 / zero // +inf. We can constant propagate this one. - negone := -1.0 - - // amd64:"DIVSD" - z0 := zero / zero - // amd64:"MULSD" - z1 := zero * inf - // amd64:"SQRTSD" - z2 := math.Sqrt(negone) - return z0 + z1 + z2 -} - -func nanGenerate32() float32 { - zero := float32(0.0) - // amd64:-"DIVSS" - inf := 1 / zero // +inf. We can constant propagate this one. - - // amd64:"DIVSS" - z0 := zero / zero - // amd64:"MULSS" - z1 := zero * inf - return z0 + z1 -}