mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
cmd/compile: optimize more pointer comparisons
The existing pointer comparison optimizations don't include pointer arithmetic. Add them. These rules trigger a few times in std cmd, while compiling: time.Duration.String cmd/go/internal/tlog.NodeHash crypto/tls.ticketKeyFromBytes (3 times) crypto/elliptic.(*p256Point).p256ScalarMult (15 times!) crypto/elliptic.initTable These weird comparisons occur when using the copy builtin, which does a pointer comparison between src and dst. This also happens to fix #32454, by optimizing enough early on that all values can be eliminated. Fixes #32454 Change-Id: I799d45743350bddd15a295dc1e12f8d03c11d1c6 Reviewed-on: https://go-review.googlesource.com/c/go/+/180940 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
abda0a6a92
commit
b8cbcacabe
@ -1904,9 +1904,17 @@
|
||||
(EqPtr x x) -> (ConstBool [1])
|
||||
(NeqPtr x x) -> (ConstBool [0])
|
||||
(EqPtr (Addr {a} _) (Addr {b} _)) -> (ConstBool [b2i(a == b)])
|
||||
(EqPtr (Addr {a} _) (OffPtr [o] (Addr {b} _))) -> (ConstBool [b2i(a == b && o == 0)])
|
||||
(EqPtr (OffPtr [o1] (Addr {a} _)) (OffPtr [o2] (Addr {b} _))) -> (ConstBool [b2i(a == b && o1 == o2)])
|
||||
(NeqPtr (Addr {a} _) (Addr {b} _)) -> (ConstBool [b2i(a != b)])
|
||||
(NeqPtr (Addr {a} _) (OffPtr [o] (Addr {b} _))) -> (ConstBool [b2i(a != b || o != 0)])
|
||||
(NeqPtr (OffPtr [o1] (Addr {a} _)) (OffPtr [o2] (Addr {b} _))) -> (ConstBool [b2i(a != b || o1 != o2)])
|
||||
(EqPtr (LocalAddr {a} _ _) (LocalAddr {b} _ _)) -> (ConstBool [b2i(a == b)])
|
||||
(EqPtr (LocalAddr {a} _ _) (OffPtr [o] (LocalAddr {b} _ _))) -> (ConstBool [b2i(a == b && o == 0)])
|
||||
(EqPtr (OffPtr [o1] (LocalAddr {a} _ _)) (OffPtr [o2] (LocalAddr {b} _ _))) -> (ConstBool [b2i(a == b && o1 == o2)])
|
||||
(NeqPtr (LocalAddr {a} _ _) (LocalAddr {b} _ _)) -> (ConstBool [b2i(a != b)])
|
||||
(NeqPtr (LocalAddr {a} _ _) (OffPtr [o] (LocalAddr {b} _ _))) -> (ConstBool [b2i(a != b || o != 0)])
|
||||
(NeqPtr (OffPtr [o1] (LocalAddr {a} _ _)) (OffPtr [o2] (LocalAddr {b} _ _))) -> (ConstBool [b2i(a != b || o1 != o2)])
|
||||
(EqPtr (OffPtr [o1] p1) p2) && isSamePtr(p1, p2) -> (ConstBool [b2i(o1 == 0)])
|
||||
(NeqPtr (OffPtr [o1] p1) p2) && isSamePtr(p1, p2) -> (ConstBool [b2i(o1 != 0)])
|
||||
(EqPtr (OffPtr [o1] p1) (OffPtr [o2] p2)) && isSamePtr(p1, p2) -> (ConstBool [b2i(o1 == o2)])
|
||||
@ -1915,7 +1923,13 @@
|
||||
(NeqPtr (Const(32|64) [c]) (Const(32|64) [d])) -> (ConstBool [b2i(c != d)])
|
||||
|
||||
(EqPtr (LocalAddr _ _) (Addr _)) -> (ConstBool [0])
|
||||
(EqPtr (OffPtr (LocalAddr _ _)) (Addr _)) -> (ConstBool [0])
|
||||
(EqPtr (LocalAddr _ _) (OffPtr (Addr _))) -> (ConstBool [0])
|
||||
(EqPtr (OffPtr (LocalAddr _ _)) (OffPtr (Addr _))) -> (ConstBool [0])
|
||||
(NeqPtr (LocalAddr _ _) (Addr _)) -> (ConstBool [1])
|
||||
(NeqPtr (OffPtr (LocalAddr _ _)) (Addr _)) -> (ConstBool [1])
|
||||
(NeqPtr (LocalAddr _ _) (OffPtr (Addr _))) -> (ConstBool [1])
|
||||
(NeqPtr (OffPtr (LocalAddr _ _)) (OffPtr (Addr _))) -> (ConstBool [1])
|
||||
|
||||
// Simplify address comparisons.
|
||||
(EqPtr (AddPtr p1 o1) p2) && isSamePtr(p1, p2) -> (Not (IsNonNil o1))
|
||||
|
@ -105,7 +105,7 @@ func rewriteValuegeneric(v *Value) bool {
|
||||
case OpEqInter:
|
||||
return rewriteValuegeneric_OpEqInter_0(v)
|
||||
case OpEqPtr:
|
||||
return rewriteValuegeneric_OpEqPtr_0(v) || rewriteValuegeneric_OpEqPtr_10(v) || rewriteValuegeneric_OpEqPtr_20(v)
|
||||
return rewriteValuegeneric_OpEqPtr_0(v) || rewriteValuegeneric_OpEqPtr_10(v) || rewriteValuegeneric_OpEqPtr_20(v) || rewriteValuegeneric_OpEqPtr_30(v)
|
||||
case OpEqSlice:
|
||||
return rewriteValuegeneric_OpEqSlice_0(v)
|
||||
case OpGeq16:
|
||||
@ -291,7 +291,7 @@ func rewriteValuegeneric(v *Value) bool {
|
||||
case OpNeqInter:
|
||||
return rewriteValuegeneric_OpNeqInter_0(v)
|
||||
case OpNeqPtr:
|
||||
return rewriteValuegeneric_OpNeqPtr_0(v) || rewriteValuegeneric_OpNeqPtr_10(v) || rewriteValuegeneric_OpNeqPtr_20(v)
|
||||
return rewriteValuegeneric_OpNeqPtr_0(v) || rewriteValuegeneric_OpNeqPtr_10(v) || rewriteValuegeneric_OpNeqPtr_20(v) || rewriteValuegeneric_OpNeqPtr_30(v)
|
||||
case OpNeqSlice:
|
||||
return rewriteValuegeneric_OpNeqSlice_0(v)
|
||||
case OpNilCheck:
|
||||
@ -27075,6 +27075,112 @@ func rewriteValuegeneric_OpEqPtr_0(v *Value) bool {
|
||||
v.AuxInt = b2i(a == b)
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr (Addr {a} _) (OffPtr [o] (Addr {b} _)))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a == b && o == 0)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
a := v_0.Aux
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o := v_1.AuxInt
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
b := v_1_0.Aux
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = b2i(a == b && o == 0)
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr (OffPtr [o] (Addr {b} _)) (Addr {a} _))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a == b && o == 0)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o := v_0.AuxInt
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
b := v_0_0.Aux
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
a := v_1.Aux
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = b2i(a == b && o == 0)
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr (OffPtr [o1] (Addr {a} _)) (OffPtr [o2] (Addr {b} _)))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a == b && o1 == o2)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o1 := v_0.AuxInt
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
a := v_0_0.Aux
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o2 := v_1.AuxInt
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
b := v_1_0.Aux
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = b2i(a == b && o1 == o2)
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr (OffPtr [o2] (Addr {b} _)) (OffPtr [o1] (Addr {a} _)))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a == b && o1 == o2)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o2 := v_0.AuxInt
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
b := v_0_0.Aux
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o1 := v_1.AuxInt
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
a := v_1_0.Aux
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = b2i(a == b && o1 == o2)
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr (LocalAddr {a} _ _) (LocalAddr {b} _ _))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a == b)])
|
||||
@ -27117,6 +27223,123 @@ func rewriteValuegeneric_OpEqPtr_0(v *Value) bool {
|
||||
v.AuxInt = b2i(a == b)
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr (LocalAddr {a} _ _) (OffPtr [o] (LocalAddr {b} _ _)))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a == b && o == 0)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
a := v_0.Aux
|
||||
_ = v_0.Args[1]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o := v_1.AuxInt
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
b := v_1_0.Aux
|
||||
_ = v_1_0.Args[1]
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = b2i(a == b && o == 0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpEqPtr_10(v *Value) bool {
|
||||
// match: (EqPtr (OffPtr [o] (LocalAddr {b} _ _)) (LocalAddr {a} _ _))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a == b && o == 0)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o := v_0.AuxInt
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
b := v_0_0.Aux
|
||||
_ = v_0_0.Args[1]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
a := v_1.Aux
|
||||
_ = v_1.Args[1]
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = b2i(a == b && o == 0)
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr (OffPtr [o1] (LocalAddr {a} _ _)) (OffPtr [o2] (LocalAddr {b} _ _)))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a == b && o1 == o2)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o1 := v_0.AuxInt
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
a := v_0_0.Aux
|
||||
_ = v_0_0.Args[1]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o2 := v_1.AuxInt
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
b := v_1_0.Aux
|
||||
_ = v_1_0.Args[1]
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = b2i(a == b && o1 == o2)
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr (OffPtr [o2] (LocalAddr {b} _ _)) (OffPtr [o1] (LocalAddr {a} _ _)))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a == b && o1 == o2)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o2 := v_0.AuxInt
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
b := v_0_0.Aux
|
||||
_ = v_0_0.Args[1]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o1 := v_1.AuxInt
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
a := v_1_0.Aux
|
||||
_ = v_1_0.Args[1]
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = b2i(a == b && o1 == o2)
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr (OffPtr [o1] p1) p2)
|
||||
// cond: isSamePtr(p1, p2)
|
||||
// result: (ConstBool [b2i(o1 == 0)])
|
||||
@ -27221,11 +27444,6 @@ func rewriteValuegeneric_OpEqPtr_0(v *Value) bool {
|
||||
v.AuxInt = b2i(c == d)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpEqPtr_10(v *Value) bool {
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (EqPtr (Const32 [d]) (Const32 [c]))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(c == d)])
|
||||
@ -27264,6 +27482,11 @@ func rewriteValuegeneric_OpEqPtr_10(v *Value) bool {
|
||||
v.AuxInt = b2i(c == d)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpEqPtr_20(v *Value) bool {
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (EqPtr (Const64 [d]) (Const64 [c]))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(c == d)])
|
||||
@ -27319,6 +27542,146 @@ func rewriteValuegeneric_OpEqPtr_10(v *Value) bool {
|
||||
v.AuxInt = 0
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr (OffPtr (LocalAddr _ _)) (Addr _))
|
||||
// cond:
|
||||
// result: (ConstBool [0])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
_ = v_0_0.Args[1]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = 0
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr (Addr _) (OffPtr (LocalAddr _ _)))
|
||||
// cond:
|
||||
// result: (ConstBool [0])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
_ = v_1_0.Args[1]
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = 0
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr (LocalAddr _ _) (OffPtr (Addr _)))
|
||||
// cond:
|
||||
// result: (ConstBool [0])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = 0
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr (OffPtr (Addr _)) (LocalAddr _ _))
|
||||
// cond:
|
||||
// result: (ConstBool [0])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
_ = v_1.Args[1]
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = 0
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr (OffPtr (LocalAddr _ _)) (OffPtr (Addr _)))
|
||||
// cond:
|
||||
// result: (ConstBool [0])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
_ = v_0_0.Args[1]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = 0
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr (OffPtr (Addr _)) (OffPtr (LocalAddr _ _)))
|
||||
// cond:
|
||||
// result: (ConstBool [0])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
_ = v_1_0.Args[1]
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = 0
|
||||
return true
|
||||
}
|
||||
// match: (EqPtr (AddPtr p1 o1) p2)
|
||||
// cond: isSamePtr(p1, p2)
|
||||
// result: (Not (IsNonNil o1))
|
||||
@ -27339,6 +27702,11 @@ func rewriteValuegeneric_OpEqPtr_10(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpEqPtr_30(v *Value) bool {
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (EqPtr p2 (AddPtr p1 o1))
|
||||
// cond: isSamePtr(p1, p2)
|
||||
// result: (Not (IsNonNil o1))
|
||||
@ -27415,11 +27783,6 @@ func rewriteValuegeneric_OpEqPtr_10(v *Value) bool {
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpEqPtr_20(v *Value) bool {
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (EqPtr p (Const64 [0]))
|
||||
// cond:
|
||||
// result: (Not (IsNonNil p))
|
||||
@ -38384,6 +38747,112 @@ func rewriteValuegeneric_OpNeqPtr_0(v *Value) bool {
|
||||
v.AuxInt = b2i(a != b)
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr (Addr {a} _) (OffPtr [o] (Addr {b} _)))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a != b || o != 0)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
a := v_0.Aux
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o := v_1.AuxInt
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
b := v_1_0.Aux
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = b2i(a != b || o != 0)
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr (OffPtr [o] (Addr {b} _)) (Addr {a} _))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a != b || o != 0)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o := v_0.AuxInt
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
b := v_0_0.Aux
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
a := v_1.Aux
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = b2i(a != b || o != 0)
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr (OffPtr [o1] (Addr {a} _)) (OffPtr [o2] (Addr {b} _)))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a != b || o1 != o2)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o1 := v_0.AuxInt
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
a := v_0_0.Aux
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o2 := v_1.AuxInt
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
b := v_1_0.Aux
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = b2i(a != b || o1 != o2)
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr (OffPtr [o2] (Addr {b} _)) (OffPtr [o1] (Addr {a} _)))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a != b || o1 != o2)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o2 := v_0.AuxInt
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
b := v_0_0.Aux
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o1 := v_1.AuxInt
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
a := v_1_0.Aux
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = b2i(a != b || o1 != o2)
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr (LocalAddr {a} _ _) (LocalAddr {b} _ _))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a != b)])
|
||||
@ -38426,6 +38895,123 @@ func rewriteValuegeneric_OpNeqPtr_0(v *Value) bool {
|
||||
v.AuxInt = b2i(a != b)
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr (LocalAddr {a} _ _) (OffPtr [o] (LocalAddr {b} _ _)))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a != b || o != 0)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
a := v_0.Aux
|
||||
_ = v_0.Args[1]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o := v_1.AuxInt
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
b := v_1_0.Aux
|
||||
_ = v_1_0.Args[1]
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = b2i(a != b || o != 0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpNeqPtr_10(v *Value) bool {
|
||||
// match: (NeqPtr (OffPtr [o] (LocalAddr {b} _ _)) (LocalAddr {a} _ _))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a != b || o != 0)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o := v_0.AuxInt
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
b := v_0_0.Aux
|
||||
_ = v_0_0.Args[1]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
a := v_1.Aux
|
||||
_ = v_1.Args[1]
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = b2i(a != b || o != 0)
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr (OffPtr [o1] (LocalAddr {a} _ _)) (OffPtr [o2] (LocalAddr {b} _ _)))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a != b || o1 != o2)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o1 := v_0.AuxInt
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
a := v_0_0.Aux
|
||||
_ = v_0_0.Args[1]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o2 := v_1.AuxInt
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
b := v_1_0.Aux
|
||||
_ = v_1_0.Args[1]
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = b2i(a != b || o1 != o2)
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr (OffPtr [o2] (LocalAddr {b} _ _)) (OffPtr [o1] (LocalAddr {a} _ _)))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(a != b || o1 != o2)])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o2 := v_0.AuxInt
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
b := v_0_0.Aux
|
||||
_ = v_0_0.Args[1]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
o1 := v_1.AuxInt
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
a := v_1_0.Aux
|
||||
_ = v_1_0.Args[1]
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = b2i(a != b || o1 != o2)
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr (OffPtr [o1] p1) p2)
|
||||
// cond: isSamePtr(p1, p2)
|
||||
// result: (ConstBool [b2i(o1 != 0)])
|
||||
@ -38530,9 +39116,6 @@ func rewriteValuegeneric_OpNeqPtr_0(v *Value) bool {
|
||||
v.AuxInt = b2i(c != d)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpNeqPtr_10(v *Value) bool {
|
||||
// match: (NeqPtr (Const32 [d]) (Const32 [c]))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(c != d)])
|
||||
@ -38571,6 +39154,9 @@ func rewriteValuegeneric_OpNeqPtr_10(v *Value) bool {
|
||||
v.AuxInt = b2i(c != d)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpNeqPtr_20(v *Value) bool {
|
||||
// match: (NeqPtr (Const64 [d]) (Const64 [c]))
|
||||
// cond:
|
||||
// result: (ConstBool [b2i(c != d)])
|
||||
@ -38626,6 +39212,146 @@ func rewriteValuegeneric_OpNeqPtr_10(v *Value) bool {
|
||||
v.AuxInt = 1
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr (OffPtr (LocalAddr _ _)) (Addr _))
|
||||
// cond:
|
||||
// result: (ConstBool [1])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
_ = v_0_0.Args[1]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = 1
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr (Addr _) (OffPtr (LocalAddr _ _)))
|
||||
// cond:
|
||||
// result: (ConstBool [1])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
_ = v_1_0.Args[1]
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = 1
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr (LocalAddr _ _) (OffPtr (Addr _)))
|
||||
// cond:
|
||||
// result: (ConstBool [1])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
_ = v_0.Args[1]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = 1
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr (OffPtr (Addr _)) (LocalAddr _ _))
|
||||
// cond:
|
||||
// result: (ConstBool [1])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
_ = v_1.Args[1]
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = 1
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr (OffPtr (LocalAddr _ _)) (OffPtr (Addr _)))
|
||||
// cond:
|
||||
// result: (ConstBool [1])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
_ = v_0_0.Args[1]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = 1
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr (OffPtr (Addr _)) (OffPtr (LocalAddr _ _)))
|
||||
// cond:
|
||||
// result: (ConstBool [1])
|
||||
for {
|
||||
_ = v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
v_0_0 := v_0.Args[0]
|
||||
if v_0_0.Op != OpAddr {
|
||||
break
|
||||
}
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
v_1_0 := v_1.Args[0]
|
||||
if v_1_0.Op != OpLocalAddr {
|
||||
break
|
||||
}
|
||||
_ = v_1_0.Args[1]
|
||||
v.reset(OpConstBool)
|
||||
v.AuxInt = 1
|
||||
return true
|
||||
}
|
||||
// match: (NeqPtr (AddPtr p1 o1) p2)
|
||||
// cond: isSamePtr(p1, p2)
|
||||
// result: (IsNonNil o1)
|
||||
@ -38644,6 +39370,9 @@ func rewriteValuegeneric_OpNeqPtr_10(v *Value) bool {
|
||||
v.AddArg(o1)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpNeqPtr_30(v *Value) bool {
|
||||
// match: (NeqPtr p2 (AddPtr p1 o1))
|
||||
// cond: isSamePtr(p1, p2)
|
||||
// result: (IsNonNil o1)
|
||||
@ -38712,9 +39441,6 @@ func rewriteValuegeneric_OpNeqPtr_10(v *Value) bool {
|
||||
v.AddArg(p)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpNeqPtr_20(v *Value) bool {
|
||||
// match: (NeqPtr p (Const64 [0]))
|
||||
// cond:
|
||||
// result: (IsNonNil p)
|
||||
|
23
test/fixedbugs/issue32454.go
Normal file
23
test/fixedbugs/issue32454.go
Normal file
@ -0,0 +1,23 @@
|
||||
// compile
|
||||
|
||||
// Copyright 2019 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.
|
||||
|
||||
package p
|
||||
|
||||
type T struct {
|
||||
s string
|
||||
f float64
|
||||
}
|
||||
|
||||
func f() {
|
||||
var f float64
|
||||
var st T
|
||||
for {
|
||||
switch &st.f {
|
||||
case &f:
|
||||
f = 1
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user