1
0
mirror of https://github.com/golang/go synced 2024-09-23 17:20:13 -06:00

cmd/compile: prevent constant folding of +/- when result is NaN

Missed as part of CL 221790. It isn't just * and / that can make NaNs.

Update #36400
Fixes #38359

Change-Id: I3fa562f772fe03b510793a6dc0cf6189c0c3e652
Reviewed-on: https://go-review.googlesource.com/c/go/+/227860
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alberto Donizetti <alb.donizetti@gmail.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
Keith Randall 2020-04-10 09:43:22 -07:00
parent 37470c0664
commit 83e288f3db
3 changed files with 39 additions and 4 deletions

View File

@ -103,8 +103,8 @@
(Add16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c+d))])
(Add32 (Const32 [c]) (Const32 [d])) -> (Const32 [int64(int32(c+d))])
(Add64 (Const64 [c]) (Const64 [d])) -> (Const64 [c+d])
(Add32F (Const32F [c]) (Const32F [d])) -> (Const32F [auxFrom32F(auxTo32F(c) + auxTo32F(d))])
(Add64F (Const64F [c]) (Const64F [d])) -> (Const64F [auxFrom64F(auxTo64F(c) + auxTo64F(d))])
(Add32F (Const32F [c]) (Const32F [d])) && !math.IsNaN(float64(auxTo32F(c) + auxTo32F(d))) -> (Const32F [auxFrom32F(auxTo32F(c) + auxTo32F(d))])
(Add64F (Const64F [c]) (Const64F [d])) && !math.IsNaN(auxTo64F(c) + auxTo64F(d)) -> (Const64F [auxFrom64F(auxTo64F(c) + auxTo64F(d))])
(AddPtr <t> x (Const64 [c])) -> (OffPtr <t> x [c])
(AddPtr <t> x (Const32 [c])) -> (OffPtr <t> x [c])
@ -112,8 +112,8 @@
(Sub16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c-d))])
(Sub32 (Const32 [c]) (Const32 [d])) -> (Const32 [int64(int32(c-d))])
(Sub64 (Const64 [c]) (Const64 [d])) -> (Const64 [c-d])
(Sub32F (Const32F [c]) (Const32F [d])) -> (Const32F [auxFrom32F(auxTo32F(c) - auxTo32F(d))])
(Sub64F (Const64F [c]) (Const64F [d])) -> (Const64F [auxFrom64F(auxTo64F(c) - auxTo64F(d))])
(Sub32F (Const32F [c]) (Const32F [d])) && !math.IsNaN(float64(auxTo32F(c) - auxTo32F(d))) -> (Const32F [auxFrom32F(auxTo32F(c) - auxTo32F(d))])
(Sub64F (Const64F [c]) (Const64F [d])) && !math.IsNaN(auxTo64F(c) - auxTo64F(d)) -> (Const64F [auxFrom64F(auxTo64F(c) - auxTo64F(d))])
(Mul8 (Const8 [c]) (Const8 [d])) -> (Const8 [int64(int8(c*d))])
(Mul16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c*d))])

View File

@ -957,6 +957,7 @@ func rewriteValuegeneric_OpAdd32F(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (Add32F (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 {
@ -968,6 +969,9 @@ func rewriteValuegeneric_OpAdd32F(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
@ -1233,6 +1237,7 @@ func rewriteValuegeneric_OpAdd64F(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (Add64F (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 {
@ -1244,6 +1249,9 @@ func rewriteValuegeneric_OpAdd64F(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
@ -22641,6 +22649,7 @@ func rewriteValuegeneric_OpSub32F(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (Sub32F (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 {
@ -22651,6 +22660,9 @@ func rewriteValuegeneric_OpSub32F(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
@ -22879,6 +22891,7 @@ func rewriteValuegeneric_OpSub64F(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (Sub64F (Const64F [c]) (Const64F [d]))
// cond: !math.IsNaN(auxTo64F(c) - auxTo64F(d))
// result: (Const64F [auxFrom64F(auxTo64F(c) - auxTo64F(d))])
for {
if v_0.Op != OpConst64F {
@ -22889,6 +22902,9 @@ func rewriteValuegeneric_OpSub64F(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

View File

@ -0,0 +1,19 @@
// compile
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Make sure NaN-NaN compiles correctly.
package p
func f() {
var st struct {
f float64
_, _ string
}
f := 1e308
st.f = 2*f - 2*f
}