Commit 95b146e8 authored by Michael Munday's avatar Michael Munday

cmd/compile: improve floating point constant propagation

Add generic rules to propagate floating point constants through
comparisons and integer conversions. These new rules seldom trigger
in the standard library so there is no performance change, however
I think it is worth adding them anyway for completeness.

Change-Id: I9db5222746508a2996f1cafb72f4e0cf2541de07
Reviewed-on: https://go-review.googlesource.com/63795
Run-TryBot: Michael Munday <mike.munday@ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarKeith Randall <khr@golang.org>
parent 40e25895
...@@ -1492,6 +1492,29 @@ var linuxS390XTests = []*asmTest{ ...@@ -1492,6 +1492,29 @@ var linuxS390XTests = []*asmTest{
`, `,
neg: []string{"\tFMOVS\t"}, neg: []string{"\tFMOVS\t"},
}, },
// Constant propagation through float comparisons.
{
fn: `
func $() bool {
return 0.5 == float64(uint32(1)) ||
1.5 > float64(uint64(1<<63)) ||
math.NaN() == math.NaN()
}
`,
pos: []string{"\tMOV(B|BZ|D)\t[$]0,"},
neg: []string{"\tFCMPU\t", "\tMOV(B|BZ|D)\t[$]1,"},
},
{
fn: `
func $() bool {
return float32(0.5) <= float32(int64(1)) &&
float32(1.5) >= float32(int32(-1<<31)) &&
float32(math.NaN()) != float32(math.NaN())
}
`,
pos: []string{"\tMOV(B|BZ|D)\t[$]1,"},
neg: []string{"\tCEBR\t", "\tMOV(B|BZ|D)\t[$]0,"},
},
} }
var linuxARMTests = []*asmTest{ var linuxARMTests = []*asmTest{
......
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
package gc package gc
import "testing" import (
"math"
"testing"
)
// For GO386=387, make sure fucomi* opcodes are not used // For GO386=387, make sure fucomi* opcodes are not used
// for comparison operations. // for comparison operations.
...@@ -29,6 +32,105 @@ func TestFloatCompare(t *testing.T) { ...@@ -29,6 +32,105 @@ func TestFloatCompare(t *testing.T) {
if !compare2(3, 5) { if !compare2(3, 5) {
t.Errorf("compare2 returned false") t.Errorf("compare2 returned false")
} }
// test folded float64 comparisons
d1, d3, d5, d9 := float64(1), float64(3), float64(5), float64(9)
if d3 == d5 {
t.Errorf("d3 == d5 returned true")
}
if d3 != d3 {
t.Errorf("d3 != d3 returned true")
}
if d3 > d5 {
t.Errorf("d3 > d5 returned true")
}
if d3 >= d9 {
t.Errorf("d3 >= d9 returned true")
}
if d5 < d1 {
t.Errorf("d5 < d1 returned true")
}
if d9 <= d1 {
t.Errorf("d9 <= d1 returned true")
}
if math.NaN() == math.NaN() {
t.Errorf("math.NaN() == math.NaN() returned true")
}
if math.NaN() >= math.NaN() {
t.Errorf("math.NaN() >= math.NaN() returned true")
}
if math.NaN() <= math.NaN() {
t.Errorf("math.NaN() <= math.NaN() returned true")
}
if math.Copysign(math.NaN(), -1) < math.NaN() {
t.Errorf("math.Copysign(math.NaN(), -1) < math.NaN() returned true")
}
if math.Inf(1) != math.Inf(1) {
t.Errorf("math.Inf(1) != math.Inf(1) returned true")
}
if math.Inf(-1) != math.Inf(-1) {
t.Errorf("math.Inf(-1) != math.Inf(-1) returned true")
}
if math.Copysign(0, -1) != 0 {
t.Errorf("math.Copysign(0, -1) != 0 returned true")
}
if math.Copysign(0, -1) < 0 {
t.Errorf("math.Copysign(0, -1) < 0 returned true")
}
if 0 > math.Copysign(0, -1) {
t.Errorf("0 > math.Copysign(0, -1) returned true")
}
// test folded float32 comparisons
s1, s3, s5, s9 := float32(1), float32(3), float32(5), float32(9)
if s3 == s5 {
t.Errorf("s3 == s5 returned true")
}
if s3 != s3 {
t.Errorf("s3 != s3 returned true")
}
if s3 > s5 {
t.Errorf("s3 > s5 returned true")
}
if s3 >= s9 {
t.Errorf("s3 >= s9 returned true")
}
if s5 < s1 {
t.Errorf("s5 < s1 returned true")
}
if s9 <= s1 {
t.Errorf("s9 <= s1 returned true")
}
sPosNaN, sNegNaN := float32(math.NaN()), float32(math.Copysign(math.NaN(), -1))
if sPosNaN == sPosNaN {
t.Errorf("sPosNaN == sPosNaN returned true")
}
if sPosNaN >= sPosNaN {
t.Errorf("sPosNaN >= sPosNaN returned true")
}
if sPosNaN <= sPosNaN {
t.Errorf("sPosNaN <= sPosNaN returned true")
}
if sNegNaN < sPosNaN {
t.Errorf("sNegNaN < sPosNaN returned true")
}
sPosInf, sNegInf := float32(math.Inf(1)), float32(math.Inf(-1))
if sPosInf != sPosInf {
t.Errorf("sPosInf != sPosInf returned true")
}
if sNegInf != sNegInf {
t.Errorf("sNegInf != sNegInf returned true")
}
sNegZero := float32(math.Copysign(0, -1))
if sNegZero != 0 {
t.Errorf("sNegZero != 0 returned true")
}
if sNegZero < 0 {
t.Errorf("sNegZero < 0 returned true")
}
if 0 > sNegZero {
t.Errorf("0 > sNegZero returned true")
}
} }
// For GO386=387, make sure fucomi* opcodes are not used // For GO386=387, make sure fucomi* opcodes are not used
......
...@@ -38,14 +38,22 @@ ...@@ -38,14 +38,22 @@
// For now, the generated successors must be a permutation of the matched successors. // For now, the generated successors must be a permutation of the matched successors.
// constant folding // constant folding
(Trunc16to8 (Const16 [c])) -> (Const8 [int64(int8(c))]) (Trunc16to8 (Const16 [c])) -> (Const8 [int64(int8(c))])
(Trunc32to8 (Const32 [c])) -> (Const8 [int64(int8(c))]) (Trunc32to8 (Const32 [c])) -> (Const8 [int64(int8(c))])
(Trunc32to16 (Const32 [c])) -> (Const16 [int64(int16(c))]) (Trunc32to16 (Const32 [c])) -> (Const16 [int64(int16(c))])
(Trunc64to8 (Const64 [c])) -> (Const8 [int64(int8(c))]) (Trunc64to8 (Const64 [c])) -> (Const8 [int64(int8(c))])
(Trunc64to16 (Const64 [c])) -> (Const16 [int64(int16(c))]) (Trunc64to16 (Const64 [c])) -> (Const16 [int64(int16(c))])
(Trunc64to32 (Const64 [c])) -> (Const32 [int64(int32(c))]) (Trunc64to32 (Const64 [c])) -> (Const32 [int64(int32(c))])
(Cvt64Fto32F (Const64F [c])) -> (Const32F [f2i(float64(i2f32(c)))]) (Cvt64Fto32F (Const64F [c])) -> (Const32F [f2i(float64(i2f32(c)))])
(Cvt32Fto64F (Const32F [c])) -> (Const64F [c]) // c is already a 64 bit float (Cvt32Fto64F (Const32F [c])) -> (Const64F [c]) // c is already a 64 bit float
(Cvt32to32F (Const32 [c])) -> (Const32F [f2i(float64(float32(int32(c))))])
(Cvt32to64F (Const32 [c])) -> (Const64F [f2i(float64(int32(c)))])
(Cvt64to32F (Const64 [c])) -> (Const32F [f2i(float64(float32(c)))])
(Cvt64to64F (Const64 [c])) -> (Const64F [f2i(float64(c))])
(Cvt32Fto32 (Const32F [c])) -> (Const32 [int64(int32(i2f(c)))])
(Cvt32Fto64 (Const32F [c])) -> (Const64 [int64(i2f(c))])
(Cvt64Fto32 (Const64F [c])) -> (Const32 [int64(int32(i2f(c)))])
(Cvt64Fto64 (Const64F [c])) -> (Const32 [int64(i2f(c))])
(Round32F x:(Const32F)) -> x (Round32F x:(Const32F)) -> x
(Round64F x:(Const64F)) -> x (Round64F x:(Const64F)) -> x
...@@ -561,6 +569,25 @@ ...@@ -561,6 +569,25 @@
(Leq16U (Const16 [c]) (Const16 [d])) -> (ConstBool [b2i(uint16(c) <= uint16(d))]) (Leq16U (Const16 [c]) (Const16 [d])) -> (ConstBool [b2i(uint16(c) <= uint16(d))])
(Leq8U (Const8 [c]) (Const8 [d])) -> (ConstBool [b2i(uint8(c) <= uint8(d))]) (Leq8U (Const8 [c]) (Const8 [d])) -> (ConstBool [b2i(uint8(c) <= uint8(d))])
// constant floating point comparisons
(Eq64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(i2f(c) == i2f(d))])
(Eq32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(i2f(c) == i2f(d))])
(Neq64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(i2f(c) != i2f(d))])
(Neq32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(i2f(c) != i2f(d))])
(Greater64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(i2f(c) > i2f(d))])
(Greater32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(i2f(c) > i2f(d))])
(Geq64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(i2f(c) >= i2f(d))])
(Geq32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(i2f(c) >= i2f(d))])
(Less64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(i2f(c) < i2f(d))])
(Less32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(i2f(c) < i2f(d))])
(Leq64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(i2f(c) <= i2f(d))])
(Leq32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(i2f(c) <= i2f(d))])
// simplifications // simplifications
(Or64 x x) -> x (Or64 x x) -> x
(Or32 x x) -> x (Or32 x x) -> x
......
...@@ -57,10 +57,26 @@ func rewriteValuegeneric(v *Value) bool { ...@@ -57,10 +57,26 @@ func rewriteValuegeneric(v *Value) bool {
return rewriteValuegeneric_OpConstString_0(v) return rewriteValuegeneric_OpConstString_0(v)
case OpConvert: case OpConvert:
return rewriteValuegeneric_OpConvert_0(v) return rewriteValuegeneric_OpConvert_0(v)
case OpCvt32Fto32:
return rewriteValuegeneric_OpCvt32Fto32_0(v)
case OpCvt32Fto64:
return rewriteValuegeneric_OpCvt32Fto64_0(v)
case OpCvt32Fto64F: case OpCvt32Fto64F:
return rewriteValuegeneric_OpCvt32Fto64F_0(v) return rewriteValuegeneric_OpCvt32Fto64F_0(v)
case OpCvt32to32F:
return rewriteValuegeneric_OpCvt32to32F_0(v)
case OpCvt32to64F:
return rewriteValuegeneric_OpCvt32to64F_0(v)
case OpCvt64Fto32:
return rewriteValuegeneric_OpCvt64Fto32_0(v)
case OpCvt64Fto32F: case OpCvt64Fto32F:
return rewriteValuegeneric_OpCvt64Fto32F_0(v) return rewriteValuegeneric_OpCvt64Fto32F_0(v)
case OpCvt64Fto64:
return rewriteValuegeneric_OpCvt64Fto64_0(v)
case OpCvt64to32F:
return rewriteValuegeneric_OpCvt64to32F_0(v)
case OpCvt64to64F:
return rewriteValuegeneric_OpCvt64to64F_0(v)
case OpDiv16: case OpDiv16:
return rewriteValuegeneric_OpDiv16_0(v) return rewriteValuegeneric_OpDiv16_0(v)
case OpDiv16u: case OpDiv16u:
...@@ -85,8 +101,12 @@ func rewriteValuegeneric(v *Value) bool { ...@@ -85,8 +101,12 @@ func rewriteValuegeneric(v *Value) bool {
return rewriteValuegeneric_OpEq16_0(v) return rewriteValuegeneric_OpEq16_0(v)
case OpEq32: case OpEq32:
return rewriteValuegeneric_OpEq32_0(v) return rewriteValuegeneric_OpEq32_0(v)
case OpEq32F:
return rewriteValuegeneric_OpEq32F_0(v)
case OpEq64: case OpEq64:
return rewriteValuegeneric_OpEq64_0(v) return rewriteValuegeneric_OpEq64_0(v)
case OpEq64F:
return rewriteValuegeneric_OpEq64F_0(v)
case OpEq8: case OpEq8:
return rewriteValuegeneric_OpEq8_0(v) return rewriteValuegeneric_OpEq8_0(v)
case OpEqB: case OpEqB:
...@@ -103,10 +123,14 @@ func rewriteValuegeneric(v *Value) bool { ...@@ -103,10 +123,14 @@ func rewriteValuegeneric(v *Value) bool {
return rewriteValuegeneric_OpGeq16U_0(v) return rewriteValuegeneric_OpGeq16U_0(v)
case OpGeq32: case OpGeq32:
return rewriteValuegeneric_OpGeq32_0(v) return rewriteValuegeneric_OpGeq32_0(v)
case OpGeq32F:
return rewriteValuegeneric_OpGeq32F_0(v)
case OpGeq32U: case OpGeq32U:
return rewriteValuegeneric_OpGeq32U_0(v) return rewriteValuegeneric_OpGeq32U_0(v)
case OpGeq64: case OpGeq64:
return rewriteValuegeneric_OpGeq64_0(v) return rewriteValuegeneric_OpGeq64_0(v)
case OpGeq64F:
return rewriteValuegeneric_OpGeq64F_0(v)
case OpGeq64U: case OpGeq64U:
return rewriteValuegeneric_OpGeq64U_0(v) return rewriteValuegeneric_OpGeq64U_0(v)
case OpGeq8: case OpGeq8:
...@@ -119,10 +143,14 @@ func rewriteValuegeneric(v *Value) bool { ...@@ -119,10 +143,14 @@ func rewriteValuegeneric(v *Value) bool {
return rewriteValuegeneric_OpGreater16U_0(v) return rewriteValuegeneric_OpGreater16U_0(v)
case OpGreater32: case OpGreater32:
return rewriteValuegeneric_OpGreater32_0(v) return rewriteValuegeneric_OpGreater32_0(v)
case OpGreater32F:
return rewriteValuegeneric_OpGreater32F_0(v)
case OpGreater32U: case OpGreater32U:
return rewriteValuegeneric_OpGreater32U_0(v) return rewriteValuegeneric_OpGreater32U_0(v)
case OpGreater64: case OpGreater64:
return rewriteValuegeneric_OpGreater64_0(v) return rewriteValuegeneric_OpGreater64_0(v)
case OpGreater64F:
return rewriteValuegeneric_OpGreater64F_0(v)
case OpGreater64U: case OpGreater64U:
return rewriteValuegeneric_OpGreater64U_0(v) return rewriteValuegeneric_OpGreater64U_0(v)
case OpGreater8: case OpGreater8:
...@@ -145,10 +173,14 @@ func rewriteValuegeneric(v *Value) bool { ...@@ -145,10 +173,14 @@ func rewriteValuegeneric(v *Value) bool {
return rewriteValuegeneric_OpLeq16U_0(v) return rewriteValuegeneric_OpLeq16U_0(v)
case OpLeq32: case OpLeq32:
return rewriteValuegeneric_OpLeq32_0(v) return rewriteValuegeneric_OpLeq32_0(v)
case OpLeq32F:
return rewriteValuegeneric_OpLeq32F_0(v)
case OpLeq32U: case OpLeq32U:
return rewriteValuegeneric_OpLeq32U_0(v) return rewriteValuegeneric_OpLeq32U_0(v)
case OpLeq64: case OpLeq64:
return rewriteValuegeneric_OpLeq64_0(v) return rewriteValuegeneric_OpLeq64_0(v)
case OpLeq64F:
return rewriteValuegeneric_OpLeq64F_0(v)
case OpLeq64U: case OpLeq64U:
return rewriteValuegeneric_OpLeq64U_0(v) return rewriteValuegeneric_OpLeq64U_0(v)
case OpLeq8: case OpLeq8:
...@@ -161,10 +193,14 @@ func rewriteValuegeneric(v *Value) bool { ...@@ -161,10 +193,14 @@ func rewriteValuegeneric(v *Value) bool {
return rewriteValuegeneric_OpLess16U_0(v) return rewriteValuegeneric_OpLess16U_0(v)
case OpLess32: case OpLess32:
return rewriteValuegeneric_OpLess32_0(v) return rewriteValuegeneric_OpLess32_0(v)
case OpLess32F:
return rewriteValuegeneric_OpLess32F_0(v)
case OpLess32U: case OpLess32U:
return rewriteValuegeneric_OpLess32U_0(v) return rewriteValuegeneric_OpLess32U_0(v)
case OpLess64: case OpLess64:
return rewriteValuegeneric_OpLess64_0(v) return rewriteValuegeneric_OpLess64_0(v)
case OpLess64F:
return rewriteValuegeneric_OpLess64F_0(v)
case OpLess64U: case OpLess64U:
return rewriteValuegeneric_OpLess64U_0(v) return rewriteValuegeneric_OpLess64U_0(v)
case OpLess8: case OpLess8:
...@@ -249,8 +285,12 @@ func rewriteValuegeneric(v *Value) bool { ...@@ -249,8 +285,12 @@ func rewriteValuegeneric(v *Value) bool {
return rewriteValuegeneric_OpNeq16_0(v) return rewriteValuegeneric_OpNeq16_0(v)
case OpNeq32: case OpNeq32:
return rewriteValuegeneric_OpNeq32_0(v) return rewriteValuegeneric_OpNeq32_0(v)
case OpNeq32F:
return rewriteValuegeneric_OpNeq32F_0(v)
case OpNeq64: case OpNeq64:
return rewriteValuegeneric_OpNeq64_0(v) return rewriteValuegeneric_OpNeq64_0(v)
case OpNeq64F:
return rewriteValuegeneric_OpNeq64F_0(v)
case OpNeq8: case OpNeq8:
return rewriteValuegeneric_OpNeq8_0(v) return rewriteValuegeneric_OpNeq8_0(v)
case OpNeqB: case OpNeqB:
...@@ -7039,6 +7079,38 @@ func rewriteValuegeneric_OpConvert_0(v *Value) bool { ...@@ -7039,6 +7079,38 @@ func rewriteValuegeneric_OpConvert_0(v *Value) bool {
} }
return false return false
} }
func rewriteValuegeneric_OpCvt32Fto32_0(v *Value) bool {
// match: (Cvt32Fto32 (Const32F [c]))
// cond:
// result: (Const32 [int64(int32(i2f(c)))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst32F {
break
}
c := v_0.AuxInt
v.reset(OpConst32)
v.AuxInt = int64(int32(i2f(c)))
return true
}
return false
}
func rewriteValuegeneric_OpCvt32Fto64_0(v *Value) bool {
// match: (Cvt32Fto64 (Const32F [c]))
// cond:
// result: (Const64 [int64(i2f(c))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst32F {
break
}
c := v_0.AuxInt
v.reset(OpConst64)
v.AuxInt = int64(i2f(c))
return true
}
return false
}
func rewriteValuegeneric_OpCvt32Fto64F_0(v *Value) bool { func rewriteValuegeneric_OpCvt32Fto64F_0(v *Value) bool {
// match: (Cvt32Fto64F (Const32F [c])) // match: (Cvt32Fto64F (Const32F [c]))
// cond: // cond:
...@@ -7055,6 +7127,54 @@ func rewriteValuegeneric_OpCvt32Fto64F_0(v *Value) bool { ...@@ -7055,6 +7127,54 @@ func rewriteValuegeneric_OpCvt32Fto64F_0(v *Value) bool {
} }
return false return false
} }
func rewriteValuegeneric_OpCvt32to32F_0(v *Value) bool {
// match: (Cvt32to32F (Const32 [c]))
// cond:
// result: (Const32F [f2i(float64(float32(int32(c))))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst32 {
break
}
c := v_0.AuxInt
v.reset(OpConst32F)
v.AuxInt = f2i(float64(float32(int32(c))))
return true
}
return false
}
func rewriteValuegeneric_OpCvt32to64F_0(v *Value) bool {
// match: (Cvt32to64F (Const32 [c]))
// cond:
// result: (Const64F [f2i(float64(int32(c)))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst32 {
break
}
c := v_0.AuxInt
v.reset(OpConst64F)
v.AuxInt = f2i(float64(int32(c)))
return true
}
return false
}
func rewriteValuegeneric_OpCvt64Fto32_0(v *Value) bool {
// match: (Cvt64Fto32 (Const64F [c]))
// cond:
// result: (Const32 [int64(int32(i2f(c)))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst64F {
break
}
c := v_0.AuxInt
v.reset(OpConst32)
v.AuxInt = int64(int32(i2f(c)))
return true
}
return false
}
func rewriteValuegeneric_OpCvt64Fto32F_0(v *Value) bool { func rewriteValuegeneric_OpCvt64Fto32F_0(v *Value) bool {
// match: (Cvt64Fto32F (Const64F [c])) // match: (Cvt64Fto32F (Const64F [c]))
// cond: // cond:
...@@ -7071,6 +7191,54 @@ func rewriteValuegeneric_OpCvt64Fto32F_0(v *Value) bool { ...@@ -7071,6 +7191,54 @@ func rewriteValuegeneric_OpCvt64Fto32F_0(v *Value) bool {
} }
return false return false
} }
func rewriteValuegeneric_OpCvt64Fto64_0(v *Value) bool {
// match: (Cvt64Fto64 (Const64F [c]))
// cond:
// result: (Const32 [int64(i2f(c))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst64F {
break
}
c := v_0.AuxInt
v.reset(OpConst32)
v.AuxInt = int64(i2f(c))
return true
}
return false
}
func rewriteValuegeneric_OpCvt64to32F_0(v *Value) bool {
// match: (Cvt64to32F (Const64 [c]))
// cond:
// result: (Const32F [f2i(float64(float32(c)))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst64 {
break
}
c := v_0.AuxInt
v.reset(OpConst32F)
v.AuxInt = f2i(float64(float32(c)))
return true
}
return false
}
func rewriteValuegeneric_OpCvt64to64F_0(v *Value) bool {
// match: (Cvt64to64F (Const64 [c]))
// cond:
// result: (Const64F [f2i(float64(c))])
for {
v_0 := v.Args[0]
if v_0.Op != OpConst64 {
break
}
c := v_0.AuxInt
v.reset(OpConst64F)
v.AuxInt = f2i(float64(c))
return true
}
return false
}
func rewriteValuegeneric_OpDiv16_0(v *Value) bool { func rewriteValuegeneric_OpDiv16_0(v *Value) bool {
b := v.Block b := v.Block
_ = b _ = b
...@@ -8933,6 +9101,47 @@ func rewriteValuegeneric_OpEq32_0(v *Value) bool { ...@@ -8933,6 +9101,47 @@ func rewriteValuegeneric_OpEq32_0(v *Value) bool {
} }
return false return false
} }
func rewriteValuegeneric_OpEq32F_0(v *Value) bool {
// match: (Eq32F (Const32F [c]) (Const32F [d]))
// cond:
// result: (ConstBool [b2i(i2f(c) == i2f(d))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpConst32F {
break
}
c := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst32F {
break
}
d := v_1.AuxInt
v.reset(OpConstBool)
v.AuxInt = b2i(i2f(c) == i2f(d))
return true
}
// match: (Eq32F (Const32F [d]) (Const32F [c]))
// cond:
// result: (ConstBool [b2i(i2f(c) == i2f(d))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpConst32F {
break
}
d := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst32F {
break
}
c := v_1.AuxInt
v.reset(OpConstBool)
v.AuxInt = b2i(i2f(c) == i2f(d))
return true
}
return false
}
func rewriteValuegeneric_OpEq64_0(v *Value) bool { func rewriteValuegeneric_OpEq64_0(v *Value) bool {
b := v.Block b := v.Block
_ = b _ = b
...@@ -9117,6 +9326,47 @@ func rewriteValuegeneric_OpEq64_0(v *Value) bool { ...@@ -9117,6 +9326,47 @@ func rewriteValuegeneric_OpEq64_0(v *Value) bool {
} }
return false return false
} }
func rewriteValuegeneric_OpEq64F_0(v *Value) bool {
// match: (Eq64F (Const64F [c]) (Const64F [d]))
// cond:
// result: (ConstBool [b2i(i2f(c) == i2f(d))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpConst64F {
break
}
c := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst64F {
break
}
d := v_1.AuxInt
v.reset(OpConstBool)
v.AuxInt = b2i(i2f(c) == i2f(d))
return true
}
// match: (Eq64F (Const64F [d]) (Const64F [c]))
// cond:
// result: (ConstBool [b2i(i2f(c) == i2f(d))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpConst64F {
break
}
d := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst64F {
break
}
c := v_1.AuxInt
v.reset(OpConstBool)
v.AuxInt = b2i(i2f(c) == i2f(d))
return true
}
return false
}
func rewriteValuegeneric_OpEq8_0(v *Value) bool { func rewriteValuegeneric_OpEq8_0(v *Value) bool {
b := v.Block b := v.Block
_ = b _ = b
...@@ -9620,6 +9870,28 @@ func rewriteValuegeneric_OpGeq32_0(v *Value) bool { ...@@ -9620,6 +9870,28 @@ func rewriteValuegeneric_OpGeq32_0(v *Value) bool {
} }
return false return false
} }
func rewriteValuegeneric_OpGeq32F_0(v *Value) bool {
// match: (Geq32F (Const32F [c]) (Const32F [d]))
// cond:
// result: (ConstBool [b2i(i2f(c) >= i2f(d))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpConst32F {
break
}
c := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst32F {
break
}
d := v_1.AuxInt
v.reset(OpConstBool)
v.AuxInt = b2i(i2f(c) >= i2f(d))
return true
}
return false
}
func rewriteValuegeneric_OpGeq32U_0(v *Value) bool { func rewriteValuegeneric_OpGeq32U_0(v *Value) bool {
// match: (Geq32U (Const32 [c]) (Const32 [d])) // match: (Geq32U (Const32 [c]) (Const32 [d]))
// cond: // cond:
...@@ -9664,6 +9936,28 @@ func rewriteValuegeneric_OpGeq64_0(v *Value) bool { ...@@ -9664,6 +9936,28 @@ func rewriteValuegeneric_OpGeq64_0(v *Value) bool {
} }
return false return false
} }
func rewriteValuegeneric_OpGeq64F_0(v *Value) bool {
// match: (Geq64F (Const64F [c]) (Const64F [d]))
// cond:
// result: (ConstBool [b2i(i2f(c) >= i2f(d))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpConst64F {
break
}
c := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst64F {
break
}
d := v_1.AuxInt
v.reset(OpConstBool)
v.AuxInt = b2i(i2f(c) >= i2f(d))
return true
}
return false
}
func rewriteValuegeneric_OpGeq64U_0(v *Value) bool { func rewriteValuegeneric_OpGeq64U_0(v *Value) bool {
// match: (Geq64U (Const64 [c]) (Const64 [d])) // match: (Geq64U (Const64 [c]) (Const64 [d]))
// cond: // cond:
...@@ -9796,6 +10090,28 @@ func rewriteValuegeneric_OpGreater32_0(v *Value) bool { ...@@ -9796,6 +10090,28 @@ func rewriteValuegeneric_OpGreater32_0(v *Value) bool {
} }
return false return false
} }
func rewriteValuegeneric_OpGreater32F_0(v *Value) bool {
// match: (Greater32F (Const32F [c]) (Const32F [d]))
// cond:
// result: (ConstBool [b2i(i2f(c) > i2f(d))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpConst32F {
break
}
c := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst32F {
break
}
d := v_1.AuxInt
v.reset(OpConstBool)
v.AuxInt = b2i(i2f(c) > i2f(d))
return true
}
return false
}
func rewriteValuegeneric_OpGreater32U_0(v *Value) bool { func rewriteValuegeneric_OpGreater32U_0(v *Value) bool {
// match: (Greater32U (Const32 [c]) (Const32 [d])) // match: (Greater32U (Const32 [c]) (Const32 [d]))
// cond: // cond:
...@@ -9840,6 +10156,28 @@ func rewriteValuegeneric_OpGreater64_0(v *Value) bool { ...@@ -9840,6 +10156,28 @@ func rewriteValuegeneric_OpGreater64_0(v *Value) bool {
} }
return false return false
} }
func rewriteValuegeneric_OpGreater64F_0(v *Value) bool {
// match: (Greater64F (Const64F [c]) (Const64F [d]))
// cond:
// result: (ConstBool [b2i(i2f(c) > i2f(d))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpConst64F {
break
}
c := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst64F {
break
}
d := v_1.AuxInt
v.reset(OpConstBool)
v.AuxInt = b2i(i2f(c) > i2f(d))
return true
}
return false
}
func rewriteValuegeneric_OpGreater64U_0(v *Value) bool { func rewriteValuegeneric_OpGreater64U_0(v *Value) bool {
// match: (Greater64U (Const64 [c]) (Const64 [d])) // match: (Greater64U (Const64 [c]) (Const64 [d]))
// cond: // cond:
...@@ -11349,6 +11687,28 @@ func rewriteValuegeneric_OpLeq32_0(v *Value) bool { ...@@ -11349,6 +11687,28 @@ func rewriteValuegeneric_OpLeq32_0(v *Value) bool {
} }
return false return false
} }
func rewriteValuegeneric_OpLeq32F_0(v *Value) bool {
// match: (Leq32F (Const32F [c]) (Const32F [d]))
// cond:
// result: (ConstBool [b2i(i2f(c) <= i2f(d))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpConst32F {
break
}
c := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst32F {
break
}
d := v_1.AuxInt
v.reset(OpConstBool)
v.AuxInt = b2i(i2f(c) <= i2f(d))
return true
}
return false
}
func rewriteValuegeneric_OpLeq32U_0(v *Value) bool { func rewriteValuegeneric_OpLeq32U_0(v *Value) bool {
// match: (Leq32U (Const32 [c]) (Const32 [d])) // match: (Leq32U (Const32 [c]) (Const32 [d]))
// cond: // cond:
...@@ -11393,6 +11753,28 @@ func rewriteValuegeneric_OpLeq64_0(v *Value) bool { ...@@ -11393,6 +11753,28 @@ func rewriteValuegeneric_OpLeq64_0(v *Value) bool {
} }
return false return false
} }
func rewriteValuegeneric_OpLeq64F_0(v *Value) bool {
// match: (Leq64F (Const64F [c]) (Const64F [d]))
// cond:
// result: (ConstBool [b2i(i2f(c) <= i2f(d))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpConst64F {
break
}
c := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst64F {
break
}
d := v_1.AuxInt
v.reset(OpConstBool)
v.AuxInt = b2i(i2f(c) <= i2f(d))
return true
}
return false
}
func rewriteValuegeneric_OpLeq64U_0(v *Value) bool { func rewriteValuegeneric_OpLeq64U_0(v *Value) bool {
// match: (Leq64U (Const64 [c]) (Const64 [d])) // match: (Leq64U (Const64 [c]) (Const64 [d]))
// cond: // cond:
...@@ -11525,6 +11907,28 @@ func rewriteValuegeneric_OpLess32_0(v *Value) bool { ...@@ -11525,6 +11907,28 @@ func rewriteValuegeneric_OpLess32_0(v *Value) bool {
} }
return false return false
} }
func rewriteValuegeneric_OpLess32F_0(v *Value) bool {
// match: (Less32F (Const32F [c]) (Const32F [d]))
// cond:
// result: (ConstBool [b2i(i2f(c) < i2f(d))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpConst32F {
break
}
c := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst32F {
break
}
d := v_1.AuxInt
v.reset(OpConstBool)
v.AuxInt = b2i(i2f(c) < i2f(d))
return true
}
return false
}
func rewriteValuegeneric_OpLess32U_0(v *Value) bool { func rewriteValuegeneric_OpLess32U_0(v *Value) bool {
// match: (Less32U (Const32 [c]) (Const32 [d])) // match: (Less32U (Const32 [c]) (Const32 [d]))
// cond: // cond:
...@@ -11569,6 +11973,28 @@ func rewriteValuegeneric_OpLess64_0(v *Value) bool { ...@@ -11569,6 +11973,28 @@ func rewriteValuegeneric_OpLess64_0(v *Value) bool {
} }
return false return false
} }
func rewriteValuegeneric_OpLess64F_0(v *Value) bool {
// match: (Less64F (Const64F [c]) (Const64F [d]))
// cond:
// result: (ConstBool [b2i(i2f(c) < i2f(d))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpConst64F {
break
}
c := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst64F {
break
}
d := v_1.AuxInt
v.reset(OpConstBool)
v.AuxInt = b2i(i2f(c) < i2f(d))
return true
}
return false
}
func rewriteValuegeneric_OpLess64U_0(v *Value) bool { func rewriteValuegeneric_OpLess64U_0(v *Value) bool {
// match: (Less64U (Const64 [c]) (Const64 [d])) // match: (Less64U (Const64 [c]) (Const64 [d]))
// cond: // cond:
...@@ -16325,6 +16751,47 @@ func rewriteValuegeneric_OpNeq32_0(v *Value) bool { ...@@ -16325,6 +16751,47 @@ func rewriteValuegeneric_OpNeq32_0(v *Value) bool {
} }
return false return false
} }
func rewriteValuegeneric_OpNeq32F_0(v *Value) bool {
// match: (Neq32F (Const32F [c]) (Const32F [d]))
// cond:
// result: (ConstBool [b2i(i2f(c) != i2f(d))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpConst32F {
break
}
c := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst32F {
break
}
d := v_1.AuxInt
v.reset(OpConstBool)
v.AuxInt = b2i(i2f(c) != i2f(d))
return true
}
// match: (Neq32F (Const32F [d]) (Const32F [c]))
// cond:
// result: (ConstBool [b2i(i2f(c) != i2f(d))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpConst32F {
break
}
d := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst32F {
break
}
c := v_1.AuxInt
v.reset(OpConstBool)
v.AuxInt = b2i(i2f(c) != i2f(d))
return true
}
return false
}
func rewriteValuegeneric_OpNeq64_0(v *Value) bool { func rewriteValuegeneric_OpNeq64_0(v *Value) bool {
b := v.Block b := v.Block
_ = b _ = b
...@@ -16509,6 +16976,47 @@ func rewriteValuegeneric_OpNeq64_0(v *Value) bool { ...@@ -16509,6 +16976,47 @@ func rewriteValuegeneric_OpNeq64_0(v *Value) bool {
} }
return false return false
} }
func rewriteValuegeneric_OpNeq64F_0(v *Value) bool {
// match: (Neq64F (Const64F [c]) (Const64F [d]))
// cond:
// result: (ConstBool [b2i(i2f(c) != i2f(d))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpConst64F {
break
}
c := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst64F {
break
}
d := v_1.AuxInt
v.reset(OpConstBool)
v.AuxInt = b2i(i2f(c) != i2f(d))
return true
}
// match: (Neq64F (Const64F [d]) (Const64F [c]))
// cond:
// result: (ConstBool [b2i(i2f(c) != i2f(d))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpConst64F {
break
}
d := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpConst64F {
break
}
c := v_1.AuxInt
v.reset(OpConstBool)
v.AuxInt = b2i(i2f(c) != i2f(d))
return true
}
return false
}
func rewriteValuegeneric_OpNeq8_0(v *Value) bool { func rewriteValuegeneric_OpNeq8_0(v *Value) bool {
b := v.Block b := v.Block
_ = b _ = b
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment