cmd/compile: improve integer comparisons with numeric bounds

This do:
- Fold always false or always true comparisons for ints and uint.
- Reduce < and <= where the true set is only one value to == with such value.

Change-Id: Ie9e3f70efd1845bef62db56543f051a50ad2532e
Reviewed-on: https://go-review.googlesource.com/c/go/+/555135
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Jorropo 2024-01-10 07:31:57 +01:00 committed by Gopher Robot
parent 370f1a88ed
commit bbd0bc22ea
4 changed files with 767 additions and 14 deletions

View file

@ -601,9 +601,49 @@
(Or(64|32|16|8) x (Or(64|32|16|8) x y)) => (Or(64|32|16|8) x y)
(Xor(64|32|16|8) x (Xor(64|32|16|8) x y)) => y
// Unsigned comparisons to zero.
(Less(64U|32U|16U|8U) _ (Const(64|32|16|8) [0])) => (ConstBool [false])
(Leq(64U|32U|16U|8U) (Const(64|32|16|8) [0]) _) => (ConstBool [true])
// Fold comparisons with numeric bounds
(Less(64|32|16|8)U _ (Const(64|32|16|8) [0])) => (ConstBool [false])
(Leq(64|32|16|8)U (Const(64|32|16|8) [0]) _) => (ConstBool [true])
(Less(64|32|16|8)U (Const(64|32|16|8) [-1]) _) => (ConstBool [false])
(Leq(64|32|16|8)U _ (Const(64|32|16|8) [-1])) => (ConstBool [true])
(Less64 _ (Const64 [math.MinInt64])) => (ConstBool [false])
(Less32 _ (Const32 [math.MinInt32])) => (ConstBool [false])
(Less16 _ (Const16 [math.MinInt16])) => (ConstBool [false])
(Less8 _ (Const8 [math.MinInt8 ])) => (ConstBool [false])
(Leq64 (Const64 [math.MinInt64]) _) => (ConstBool [true])
(Leq32 (Const32 [math.MinInt32]) _) => (ConstBool [true])
(Leq16 (Const16 [math.MinInt16]) _) => (ConstBool [true])
(Leq8 (Const8 [math.MinInt8 ]) _) => (ConstBool [true])
(Less64 (Const64 [math.MaxInt64]) _) => (ConstBool [false])
(Less32 (Const32 [math.MaxInt32]) _) => (ConstBool [false])
(Less16 (Const16 [math.MaxInt16]) _) => (ConstBool [false])
(Less8 (Const8 [math.MaxInt8 ]) _) => (ConstBool [false])
(Leq64 _ (Const64 [math.MaxInt64])) => (ConstBool [true])
(Leq32 _ (Const32 [math.MaxInt32])) => (ConstBool [true])
(Leq16 _ (Const16 [math.MaxInt16])) => (ConstBool [true])
(Leq8 _ (Const8 [math.MaxInt8 ])) => (ConstBool [true])
// Canonicalize <= on numeric bounds and < near numeric bounds to ==
(Leq(64|32|16|8)U x c:(Const(64|32|16|8) [0])) => (Eq(64|32|16|8) x c)
(Leq(64|32|16|8)U c:(Const(64|32|16|8) [-1]) x) => (Eq(64|32|16|8) x c)
(Less(64|32|16|8)U x (Const(64|32|16|8) <t> [1])) => (Eq(64|32|16|8) x (Const(64|32|16|8) <t> [0]))
(Less(64|32|16|8)U (Const(64|32|16|8) <t> [-2]) x) => (Eq(64|32|16|8) x (Const(64|32|16|8) <t> [-1]))
(Leq64 x c:(Const64 [math.MinInt64])) => (Eq64 x c)
(Leq32 x c:(Const32 [math.MinInt32])) => (Eq32 x c)
(Leq16 x c:(Const16 [math.MinInt16])) => (Eq16 x c)
(Leq8 x c:(Const8 [math.MinInt8 ])) => (Eq8 x c)
(Leq64 c:(Const64 [math.MaxInt64]) x) => (Eq64 x c)
(Leq32 c:(Const32 [math.MaxInt32]) x) => (Eq32 x c)
(Leq16 c:(Const16 [math.MaxInt16]) x) => (Eq16 x c)
(Leq8 c:(Const8 [math.MaxInt8 ]) x) => (Eq8 x c)
(Less64 x (Const64 <t> [math.MinInt64+1])) => (Eq64 x (Const64 <t> [math.MinInt64]))
(Less32 x (Const32 <t> [math.MinInt32+1])) => (Eq32 x (Const32 <t> [math.MinInt32]))
(Less16 x (Const16 <t> [math.MinInt16+1])) => (Eq16 x (Const16 <t> [math.MinInt16]))
(Less8 x (Const8 <t> [math.MinInt8 +1])) => (Eq8 x (Const8 <t> [math.MinInt8 ]))
(Less64 (Const64 <t> [math.MaxInt64-1]) x) => (Eq64 x (Const64 <t> [math.MaxInt64]))
(Less32 (Const32 <t> [math.MaxInt32-1]) x) => (Eq32 x (Const32 <t> [math.MaxInt32]))
(Less16 (Const16 <t> [math.MaxInt16-1]) x) => (Eq16 x (Const16 <t> [math.MaxInt16]))
(Less8 (Const8 <t> [math.MaxInt8 -1]) x) => (Eq8 x (Const8 <t> [math.MaxInt8 ]))
// Ands clear bits. Ors set bits.
// If a subsequent Or will set all the bits

View file

@ -11443,6 +11443,50 @@ func rewriteValuegeneric_OpLeq16(v *Value) bool {
v.AddArg2(v0, x)
return true
}
// match: (Leq16 (Const16 [math.MinInt16]) _)
// result: (ConstBool [true])
for {
if v_0.Op != OpConst16 || auxIntToInt16(v_0.AuxInt) != math.MinInt16 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(true)
return true
}
// match: (Leq16 _ (Const16 [math.MaxInt16]))
// result: (ConstBool [true])
for {
if v_1.Op != OpConst16 || auxIntToInt16(v_1.AuxInt) != math.MaxInt16 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(true)
return true
}
// match: (Leq16 x c:(Const16 [math.MinInt16]))
// result: (Eq16 x c)
for {
x := v_0
c := v_1
if c.Op != OpConst16 || auxIntToInt16(c.AuxInt) != math.MinInt16 {
break
}
v.reset(OpEq16)
v.AddArg2(x, c)
return true
}
// match: (Leq16 c:(Const16 [math.MaxInt16]) x)
// result: (Eq16 x c)
for {
c := v_0
if c.Op != OpConst16 || auxIntToInt16(c.AuxInt) != math.MaxInt16 {
break
}
x := v_1
v.reset(OpEq16)
v.AddArg2(x, c)
return true
}
return false
}
func rewriteValuegeneric_OpLeq16U(v *Value) bool {
@ -11491,6 +11535,40 @@ func rewriteValuegeneric_OpLeq16U(v *Value) bool {
v.AuxInt = boolToAuxInt(true)
return true
}
// match: (Leq16U _ (Const16 [-1]))
// result: (ConstBool [true])
for {
if v_1.Op != OpConst16 || auxIntToInt16(v_1.AuxInt) != -1 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(true)
return true
}
// match: (Leq16U x c:(Const16 [0]))
// result: (Eq16 x c)
for {
x := v_0
c := v_1
if c.Op != OpConst16 || auxIntToInt16(c.AuxInt) != 0 {
break
}
v.reset(OpEq16)
v.AddArg2(x, c)
return true
}
// match: (Leq16U c:(Const16 [-1]) x)
// result: (Eq16 x c)
for {
c := v_0
if c.Op != OpConst16 || auxIntToInt16(c.AuxInt) != -1 {
break
}
x := v_1
v.reset(OpEq16)
v.AddArg2(x, c)
return true
}
return false
}
func rewriteValuegeneric_OpLeq32(v *Value) bool {
@ -11590,6 +11668,50 @@ func rewriteValuegeneric_OpLeq32(v *Value) bool {
v.AddArg2(v0, x)
return true
}
// match: (Leq32 (Const32 [math.MinInt32]) _)
// result: (ConstBool [true])
for {
if v_0.Op != OpConst32 || auxIntToInt32(v_0.AuxInt) != math.MinInt32 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(true)
return true
}
// match: (Leq32 _ (Const32 [math.MaxInt32]))
// result: (ConstBool [true])
for {
if v_1.Op != OpConst32 || auxIntToInt32(v_1.AuxInt) != math.MaxInt32 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(true)
return true
}
// match: (Leq32 x c:(Const32 [math.MinInt32]))
// result: (Eq32 x c)
for {
x := v_0
c := v_1
if c.Op != OpConst32 || auxIntToInt32(c.AuxInt) != math.MinInt32 {
break
}
v.reset(OpEq32)
v.AddArg2(x, c)
return true
}
// match: (Leq32 c:(Const32 [math.MaxInt32]) x)
// result: (Eq32 x c)
for {
c := v_0
if c.Op != OpConst32 || auxIntToInt32(c.AuxInt) != math.MaxInt32 {
break
}
x := v_1
v.reset(OpEq32)
v.AddArg2(x, c)
return true
}
return false
}
func rewriteValuegeneric_OpLeq32F(v *Value) bool {
@ -11658,6 +11780,40 @@ func rewriteValuegeneric_OpLeq32U(v *Value) bool {
v.AuxInt = boolToAuxInt(true)
return true
}
// match: (Leq32U _ (Const32 [-1]))
// result: (ConstBool [true])
for {
if v_1.Op != OpConst32 || auxIntToInt32(v_1.AuxInt) != -1 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(true)
return true
}
// match: (Leq32U x c:(Const32 [0]))
// result: (Eq32 x c)
for {
x := v_0
c := v_1
if c.Op != OpConst32 || auxIntToInt32(c.AuxInt) != 0 {
break
}
v.reset(OpEq32)
v.AddArg2(x, c)
return true
}
// match: (Leq32U c:(Const32 [-1]) x)
// result: (Eq32 x c)
for {
c := v_0
if c.Op != OpConst32 || auxIntToInt32(c.AuxInt) != -1 {
break
}
x := v_1
v.reset(OpEq32)
v.AddArg2(x, c)
return true
}
return false
}
func rewriteValuegeneric_OpLeq64(v *Value) bool {
@ -11757,6 +11913,50 @@ func rewriteValuegeneric_OpLeq64(v *Value) bool {
v.AddArg2(v0, x)
return true
}
// match: (Leq64 (Const64 [math.MinInt64]) _)
// result: (ConstBool [true])
for {
if v_0.Op != OpConst64 || auxIntToInt64(v_0.AuxInt) != math.MinInt64 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(true)
return true
}
// match: (Leq64 _ (Const64 [math.MaxInt64]))
// result: (ConstBool [true])
for {
if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != math.MaxInt64 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(true)
return true
}
// match: (Leq64 x c:(Const64 [math.MinInt64]))
// result: (Eq64 x c)
for {
x := v_0
c := v_1
if c.Op != OpConst64 || auxIntToInt64(c.AuxInt) != math.MinInt64 {
break
}
v.reset(OpEq64)
v.AddArg2(x, c)
return true
}
// match: (Leq64 c:(Const64 [math.MaxInt64]) x)
// result: (Eq64 x c)
for {
c := v_0
if c.Op != OpConst64 || auxIntToInt64(c.AuxInt) != math.MaxInt64 {
break
}
x := v_1
v.reset(OpEq64)
v.AddArg2(x, c)
return true
}
return false
}
func rewriteValuegeneric_OpLeq64F(v *Value) bool {
@ -11825,6 +12025,40 @@ func rewriteValuegeneric_OpLeq64U(v *Value) bool {
v.AuxInt = boolToAuxInt(true)
return true
}
// match: (Leq64U _ (Const64 [-1]))
// result: (ConstBool [true])
for {
if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != -1 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(true)
return true
}
// match: (Leq64U x c:(Const64 [0]))
// result: (Eq64 x c)
for {
x := v_0
c := v_1
if c.Op != OpConst64 || auxIntToInt64(c.AuxInt) != 0 {
break
}
v.reset(OpEq64)
v.AddArg2(x, c)
return true
}
// match: (Leq64U c:(Const64 [-1]) x)
// result: (Eq64 x c)
for {
c := v_0
if c.Op != OpConst64 || auxIntToInt64(c.AuxInt) != -1 {
break
}
x := v_1
v.reset(OpEq64)
v.AddArg2(x, c)
return true
}
return false
}
func rewriteValuegeneric_OpLeq8(v *Value) bool {
@ -11924,6 +12158,50 @@ func rewriteValuegeneric_OpLeq8(v *Value) bool {
v.AddArg2(v0, x)
return true
}
// match: (Leq8 (Const8 [math.MinInt8 ]) _)
// result: (ConstBool [true])
for {
if v_0.Op != OpConst8 || auxIntToInt8(v_0.AuxInt) != math.MinInt8 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(true)
return true
}
// match: (Leq8 _ (Const8 [math.MaxInt8 ]))
// result: (ConstBool [true])
for {
if v_1.Op != OpConst8 || auxIntToInt8(v_1.AuxInt) != math.MaxInt8 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(true)
return true
}
// match: (Leq8 x c:(Const8 [math.MinInt8 ]))
// result: (Eq8 x c)
for {
x := v_0
c := v_1
if c.Op != OpConst8 || auxIntToInt8(c.AuxInt) != math.MinInt8 {
break
}
v.reset(OpEq8)
v.AddArg2(x, c)
return true
}
// match: (Leq8 c:(Const8 [math.MaxInt8 ]) x)
// result: (Eq8 x c)
for {
c := v_0
if c.Op != OpConst8 || auxIntToInt8(c.AuxInt) != math.MaxInt8 {
break
}
x := v_1
v.reset(OpEq8)
v.AddArg2(x, c)
return true
}
return false
}
func rewriteValuegeneric_OpLeq8U(v *Value) bool {
@ -11972,6 +12250,40 @@ func rewriteValuegeneric_OpLeq8U(v *Value) bool {
v.AuxInt = boolToAuxInt(true)
return true
}
// match: (Leq8U _ (Const8 [-1]))
// result: (ConstBool [true])
for {
if v_1.Op != OpConst8 || auxIntToInt8(v_1.AuxInt) != -1 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(true)
return true
}
// match: (Leq8U x c:(Const8 [0]))
// result: (Eq8 x c)
for {
x := v_0
c := v_1
if c.Op != OpConst8 || auxIntToInt8(c.AuxInt) != 0 {
break
}
v.reset(OpEq8)
v.AddArg2(x, c)
return true
}
// match: (Leq8U c:(Const8 [-1]) x)
// result: (Eq8 x c)
for {
c := v_0
if c.Op != OpConst8 || auxIntToInt8(c.AuxInt) != -1 {
break
}
x := v_1
v.reset(OpEq8)
v.AddArg2(x, c)
return true
}
return false
}
func rewriteValuegeneric_OpLess16(v *Value) bool {
@ -12066,6 +12378,60 @@ func rewriteValuegeneric_OpLess16(v *Value) bool {
v.AddArg2(v0, x)
return true
}
// match: (Less16 _ (Const16 [math.MinInt16]))
// result: (ConstBool [false])
for {
if v_1.Op != OpConst16 || auxIntToInt16(v_1.AuxInt) != math.MinInt16 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(false)
return true
}
// match: (Less16 (Const16 [math.MaxInt16]) _)
// result: (ConstBool [false])
for {
if v_0.Op != OpConst16 || auxIntToInt16(v_0.AuxInt) != math.MaxInt16 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(false)
return true
}
// match: (Less16 x (Const16 <t> [math.MinInt16+1]))
// result: (Eq16 x (Const16 <t> [math.MinInt16]))
for {
x := v_0
if v_1.Op != OpConst16 {
break
}
t := v_1.Type
if auxIntToInt16(v_1.AuxInt) != math.MinInt16+1 {
break
}
v.reset(OpEq16)
v0 := b.NewValue0(v.Pos, OpConst16, t)
v0.AuxInt = int16ToAuxInt(math.MinInt16)
v.AddArg2(x, v0)
return true
}
// match: (Less16 (Const16 <t> [math.MaxInt16-1]) x)
// result: (Eq16 x (Const16 <t> [math.MaxInt16]))
for {
if v_0.Op != OpConst16 {
break
}
t := v_0.Type
if auxIntToInt16(v_0.AuxInt) != math.MaxInt16-1 {
break
}
x := v_1
v.reset(OpEq16)
v0 := b.NewValue0(v.Pos, OpConst16, t)
v0.AuxInt = int16ToAuxInt(math.MaxInt16)
v.AddArg2(x, v0)
return true
}
return false
}
func rewriteValuegeneric_OpLess16U(v *Value) bool {
@ -12114,6 +12480,50 @@ func rewriteValuegeneric_OpLess16U(v *Value) bool {
v.AuxInt = boolToAuxInt(false)
return true
}
// match: (Less16U (Const16 [-1]) _)
// result: (ConstBool [false])
for {
if v_0.Op != OpConst16 || auxIntToInt16(v_0.AuxInt) != -1 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(false)
return true
}
// match: (Less16U x (Const16 <t> [1]))
// result: (Eq16 x (Const16 <t> [0]))
for {
x := v_0
if v_1.Op != OpConst16 {
break
}
t := v_1.Type
if auxIntToInt16(v_1.AuxInt) != 1 {
break
}
v.reset(OpEq16)
v0 := b.NewValue0(v.Pos, OpConst16, t)
v0.AuxInt = int16ToAuxInt(0)
v.AddArg2(x, v0)
return true
}
// match: (Less16U (Const16 <t> [-2]) x)
// result: (Eq16 x (Const16 <t> [-1]))
for {
if v_0.Op != OpConst16 {
break
}
t := v_0.Type
if auxIntToInt16(v_0.AuxInt) != -2 {
break
}
x := v_1
v.reset(OpEq16)
v0 := b.NewValue0(v.Pos, OpConst16, t)
v0.AuxInt = int16ToAuxInt(-1)
v.AddArg2(x, v0)
return true
}
return false
}
func rewriteValuegeneric_OpLess32(v *Value) bool {
@ -12208,6 +12618,60 @@ func rewriteValuegeneric_OpLess32(v *Value) bool {
v.AddArg2(v0, x)
return true
}
// match: (Less32 _ (Const32 [math.MinInt32]))
// result: (ConstBool [false])
for {
if v_1.Op != OpConst32 || auxIntToInt32(v_1.AuxInt) != math.MinInt32 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(false)
return true
}
// match: (Less32 (Const32 [math.MaxInt32]) _)
// result: (ConstBool [false])
for {
if v_0.Op != OpConst32 || auxIntToInt32(v_0.AuxInt) != math.MaxInt32 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(false)
return true
}
// match: (Less32 x (Const32 <t> [math.MinInt32+1]))
// result: (Eq32 x (Const32 <t> [math.MinInt32]))
for {
x := v_0
if v_1.Op != OpConst32 {
break
}
t := v_1.Type
if auxIntToInt32(v_1.AuxInt) != math.MinInt32+1 {
break
}
v.reset(OpEq32)
v0 := b.NewValue0(v.Pos, OpConst32, t)
v0.AuxInt = int32ToAuxInt(math.MinInt32)
v.AddArg2(x, v0)
return true
}
// match: (Less32 (Const32 <t> [math.MaxInt32-1]) x)
// result: (Eq32 x (Const32 <t> [math.MaxInt32]))
for {
if v_0.Op != OpConst32 {
break
}
t := v_0.Type
if auxIntToInt32(v_0.AuxInt) != math.MaxInt32-1 {
break
}
x := v_1
v.reset(OpEq32)
v0 := b.NewValue0(v.Pos, OpConst32, t)
v0.AuxInt = int32ToAuxInt(math.MaxInt32)
v.AddArg2(x, v0)
return true
}
return false
}
func rewriteValuegeneric_OpLess32F(v *Value) bool {
@ -12276,6 +12740,50 @@ func rewriteValuegeneric_OpLess32U(v *Value) bool {
v.AuxInt = boolToAuxInt(false)
return true
}
// match: (Less32U (Const32 [-1]) _)
// result: (ConstBool [false])
for {
if v_0.Op != OpConst32 || auxIntToInt32(v_0.AuxInt) != -1 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(false)
return true
}
// match: (Less32U x (Const32 <t> [1]))
// result: (Eq32 x (Const32 <t> [0]))
for {
x := v_0
if v_1.Op != OpConst32 {
break
}
t := v_1.Type
if auxIntToInt32(v_1.AuxInt) != 1 {
break
}
v.reset(OpEq32)
v0 := b.NewValue0(v.Pos, OpConst32, t)
v0.AuxInt = int32ToAuxInt(0)
v.AddArg2(x, v0)
return true
}
// match: (Less32U (Const32 <t> [-2]) x)
// result: (Eq32 x (Const32 <t> [-1]))
for {
if v_0.Op != OpConst32 {
break
}
t := v_0.Type
if auxIntToInt32(v_0.AuxInt) != -2 {
break
}
x := v_1
v.reset(OpEq32)
v0 := b.NewValue0(v.Pos, OpConst32, t)
v0.AuxInt = int32ToAuxInt(-1)
v.AddArg2(x, v0)
return true
}
return false
}
func rewriteValuegeneric_OpLess64(v *Value) bool {
@ -12370,6 +12878,60 @@ func rewriteValuegeneric_OpLess64(v *Value) bool {
v.AddArg2(v0, x)
return true
}
// match: (Less64 _ (Const64 [math.MinInt64]))
// result: (ConstBool [false])
for {
if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != math.MinInt64 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(false)
return true
}
// match: (Less64 (Const64 [math.MaxInt64]) _)
// result: (ConstBool [false])
for {
if v_0.Op != OpConst64 || auxIntToInt64(v_0.AuxInt) != math.MaxInt64 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(false)
return true
}
// match: (Less64 x (Const64 <t> [math.MinInt64+1]))
// result: (Eq64 x (Const64 <t> [math.MinInt64]))
for {
x := v_0
if v_1.Op != OpConst64 {
break
}
t := v_1.Type
if auxIntToInt64(v_1.AuxInt) != math.MinInt64+1 {
break
}
v.reset(OpEq64)
v0 := b.NewValue0(v.Pos, OpConst64, t)
v0.AuxInt = int64ToAuxInt(math.MinInt64)
v.AddArg2(x, v0)
return true
}
// match: (Less64 (Const64 <t> [math.MaxInt64-1]) x)
// result: (Eq64 x (Const64 <t> [math.MaxInt64]))
for {
if v_0.Op != OpConst64 {
break
}
t := v_0.Type
if auxIntToInt64(v_0.AuxInt) != math.MaxInt64-1 {
break
}
x := v_1
v.reset(OpEq64)
v0 := b.NewValue0(v.Pos, OpConst64, t)
v0.AuxInt = int64ToAuxInt(math.MaxInt64)
v.AddArg2(x, v0)
return true
}
return false
}
func rewriteValuegeneric_OpLess64F(v *Value) bool {
@ -12438,6 +13000,50 @@ func rewriteValuegeneric_OpLess64U(v *Value) bool {
v.AuxInt = boolToAuxInt(false)
return true
}
// match: (Less64U (Const64 [-1]) _)
// result: (ConstBool [false])
for {
if v_0.Op != OpConst64 || auxIntToInt64(v_0.AuxInt) != -1 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(false)
return true
}
// match: (Less64U x (Const64 <t> [1]))
// result: (Eq64 x (Const64 <t> [0]))
for {
x := v_0
if v_1.Op != OpConst64 {
break
}
t := v_1.Type
if auxIntToInt64(v_1.AuxInt) != 1 {
break
}
v.reset(OpEq64)
v0 := b.NewValue0(v.Pos, OpConst64, t)
v0.AuxInt = int64ToAuxInt(0)
v.AddArg2(x, v0)
return true
}
// match: (Less64U (Const64 <t> [-2]) x)
// result: (Eq64 x (Const64 <t> [-1]))
for {
if v_0.Op != OpConst64 {
break
}
t := v_0.Type
if auxIntToInt64(v_0.AuxInt) != -2 {
break
}
x := v_1
v.reset(OpEq64)
v0 := b.NewValue0(v.Pos, OpConst64, t)
v0.AuxInt = int64ToAuxInt(-1)
v.AddArg2(x, v0)
return true
}
return false
}
func rewriteValuegeneric_OpLess8(v *Value) bool {
@ -12532,6 +13138,60 @@ func rewriteValuegeneric_OpLess8(v *Value) bool {
v.AddArg2(v0, x)
return true
}
// match: (Less8 _ (Const8 [math.MinInt8 ]))
// result: (ConstBool [false])
for {
if v_1.Op != OpConst8 || auxIntToInt8(v_1.AuxInt) != math.MinInt8 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(false)
return true
}
// match: (Less8 (Const8 [math.MaxInt8 ]) _)
// result: (ConstBool [false])
for {
if v_0.Op != OpConst8 || auxIntToInt8(v_0.AuxInt) != math.MaxInt8 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(false)
return true
}
// match: (Less8 x (Const8 <t> [math.MinInt8 +1]))
// result: (Eq8 x (Const8 <t> [math.MinInt8 ]))
for {
x := v_0
if v_1.Op != OpConst8 {
break
}
t := v_1.Type
if auxIntToInt8(v_1.AuxInt) != math.MinInt8+1 {
break
}
v.reset(OpEq8)
v0 := b.NewValue0(v.Pos, OpConst8, t)
v0.AuxInt = int8ToAuxInt(math.MinInt8)
v.AddArg2(x, v0)
return true
}
// match: (Less8 (Const8 <t> [math.MaxInt8 -1]) x)
// result: (Eq8 x (Const8 <t> [math.MaxInt8 ]))
for {
if v_0.Op != OpConst8 {
break
}
t := v_0.Type
if auxIntToInt8(v_0.AuxInt) != math.MaxInt8-1 {
break
}
x := v_1
v.reset(OpEq8)
v0 := b.NewValue0(v.Pos, OpConst8, t)
v0.AuxInt = int8ToAuxInt(math.MaxInt8)
v.AddArg2(x, v0)
return true
}
return false
}
func rewriteValuegeneric_OpLess8U(v *Value) bool {
@ -12580,6 +13240,50 @@ func rewriteValuegeneric_OpLess8U(v *Value) bool {
v.AuxInt = boolToAuxInt(false)
return true
}
// match: (Less8U (Const8 [-1]) _)
// result: (ConstBool [false])
for {
if v_0.Op != OpConst8 || auxIntToInt8(v_0.AuxInt) != -1 {
break
}
v.reset(OpConstBool)
v.AuxInt = boolToAuxInt(false)
return true
}
// match: (Less8U x (Const8 <t> [1]))
// result: (Eq8 x (Const8 <t> [0]))
for {
x := v_0
if v_1.Op != OpConst8 {
break
}
t := v_1.Type
if auxIntToInt8(v_1.AuxInt) != 1 {
break
}
v.reset(OpEq8)
v0 := b.NewValue0(v.Pos, OpConst8, t)
v0.AuxInt = int8ToAuxInt(0)
v.AddArg2(x, v0)
return true
}
// match: (Less8U (Const8 <t> [-2]) x)
// result: (Eq8 x (Const8 <t> [-1]))
for {
if v_0.Op != OpConst8 {
break
}
t := v_0.Type
if auxIntToInt8(v_0.AuxInt) != -2 {
break
}
x := v_1
v.reset(OpEq8)
v0 := b.NewValue0(v.Pos, OpConst8, t)
v0.AuxInt = int8ToAuxInt(-1)
v.AddArg2(x, v0)
return true
}
return false
}
func rewriteValuegeneric_OpLoad(v *Value) bool {

View file

@ -33,7 +33,7 @@ func fEqLessU(a uint, f float64) bool {
}
func fEqLeqU(a uint64, f float64) bool {
return a == 0 && f > Cf2 || a <= 0 && f < -Cf2 // ERROR "Redirect Leq64U based on Eq64$"
return a == 0 && f > Cf2 || a <= 0 && f < -Cf2 // ERROR "Redirect Eq64 based on Eq64$"
}
func fNeqEq(a int, f float64) bool {
@ -58,7 +58,7 @@ func fNeqLessU(a uint, f float64) bool {
}
func fNeqLeqU(a uint32, f float64) bool {
return a != 0 && f > Cf2 || a <= 0 && f < -Cf2 // ERROR "Redirect Leq32U based on Neq32$"
return a != 2 && f > Cf2 || a <= 2 && f < -Cf2 // ERROR "Redirect Leq32U based on Neq32$"
}
func fLessEq(a int, f float64) bool {
@ -110,11 +110,11 @@ func fLessULeqU(a uint64, f float64) bool {
}
func fLeqUEq(a uint8, f float64) bool {
return a <= 0 && f > Cf2 || a == 0 && f < -Cf2 // ERROR "Redirect Eq8 based on Leq8U$"
return a <= 2 && f > Cf2 || a == 2 && f < -Cf2 // ERROR "Redirect Eq8 based on Leq8U$"
}
func fLeqUNeq(a uint16, f float64) bool {
return a <= 0 && f > Cf2 || a != 0 && f < -Cf2 // ERROR "Redirect Neq16 based on Leq16U$"
return a <= 2 && f > Cf2 || a != 2 && f < -Cf2 // ERROR "Redirect Neq16 based on Leq16U$"
}
func fLeqLessU(a uint32, f float64) bool {
@ -122,7 +122,7 @@ func fLeqLessU(a uint32, f float64) bool {
}
func fLeqLeqU(a uint64, f float64) bool {
return a <= 0 && f > Cf2 || a <= 0 && f < -Cf2 // ERROR "Redirect Leq64U based on Leq64U$"
return a <= 2 && f > Cf2 || a <= 2 && f < -Cf2 // ERROR "Redirect Leq64U based on Leq64U$"
}
// Arg tests are disabled because the op name is different on amd64 and arm64.

View file

@ -396,8 +396,11 @@ func f13e(a int) int {
return 0
}
func f13f(a int64) int64 {
if a > math.MaxInt64 {
func f13f(a, b int64) int64 {
if b != math.MaxInt64 {
return 42
}
if a > b {
if a == 0 { // ERROR "Disproved Eq64$"
return 1
}
@ -869,9 +872,12 @@ func unrollInclStepTooLarge(a []int) int {
}
// Not an induction variable (min too small, iterating down)
func unrollDecMin(a []int) int {
func unrollDecMin(a []int, b int) int {
if b != math.MinInt64 {
return 42
}
var i, x int
for i = len(a); i >= math.MinInt64; i -= 2 {
for i = len(a); i >= b; i -= 2 {
x += a[i-1]
x += a[i-2]
}
@ -882,9 +888,12 @@ func unrollDecMin(a []int) int {
}
// Not an induction variable (min too small, iterating up -- perhaps could allow, but why bother?)
func unrollIncMin(a []int) int {
func unrollIncMin(a []int, b int) int {
if b != math.MinInt64 {
return 42
}
var i, x int
for i = len(a); i >= math.MinInt64; i += 2 {
for i = len(a); i >= b; i += 2 {
x += a[i-1]
x += a[i-2]
}