aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Munday <mike.munday@ibm.com>2018-04-12 15:24:08 +0100
committerMichael Munday <mike.munday@ibm.com>2018-04-16 20:43:57 +0000
commit58cdecb9c8d04d7eb1209d2877d541d34e23c9d3 (patch)
tree8197fada4944867509fbd2e66563a49fdbf44008 /src
parent89d576c933442ce0e3e78686db17a05de0a3dc8c (diff)
downloadgo-58cdecb9c8d04d7eb1209d2877d541d34e23c9d3.tar.xz
cmd/compile: generate constants for NeqPtr, EqPtr and IsNonNil ops
If both inputs are constant offsets from the same pointer then we can evaluate NeqPtr and EqPtr at compile time. Triggers a few times during all.bash. Removes a conditional branch in the following code: copy(x[1:], x[:]) This branch was recently added as an optimization in CL 94596. We now skip the memmove if the pointers are equal. However, in the above code we know at compile time that they are never equal. Also, when the offset is variable, check if the offset is zero rather than if the pointers are equal. For example: copy(x[a:], x[:]) This would now skip the copy if a == 0, rather than if x + a == x. Finally I've also added a rule to make IsNonNil true for pointers to values on the stack. The nil check elimination pass will catch these anyway, but eliminating them here might eliminate branches earlier. Change-Id: If72f436fef0a96ad0f4e296d3a1f8b6c3e712085 Reviewed-on: https://go-review.googlesource.com/106635 Run-TryBot: Michael Munday <mike.munday@ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/ssa/gen/generic.rules32
-rw-r--r--src/cmd/compile/internal/ssa/rewritegeneric.go724
2 files changed, 675 insertions, 81 deletions
diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules
index 06f32490d2..b554e99a4c 100644
--- a/src/cmd/compile/internal/ssa/gen/generic.rules
+++ b/src/cmd/compile/internal/ssa/gen/generic.rules
@@ -528,11 +528,6 @@
(Phi (Const32 [c]) (Const32 [c])) -> (Const32 [c])
(Phi (Const64 [c]) (Const64 [c])) -> (Const64 [c])
-// user nil checks
-(NeqPtr p (ConstNil)) -> (IsNonNil p)
-(EqPtr p (ConstNil)) -> (Not (IsNonNil p))
-(IsNonNil (ConstNil)) -> (ConstBool [0])
-
// slice and interface comparisons
// The frontend ensures that we can only compare against nil,
// so we need only compare the first word (interface type or slice ptr).
@@ -1241,11 +1236,30 @@
&& warnRule(fe.Debug_checknil() && v.Pos.Line() > 1, v, "removed nil check")
-> (Invalid)
-// Address comparison shows up in type assertions.
-(EqPtr x x) -> (ConstBool [1])
-(EqPtr (Addr {a} x) (Addr {b} x)) -> (ConstBool [b2i(a == b)])
+// Evaluate constant address comparisons.
+(EqPtr x x) -> (ConstBool [1])
(NeqPtr x x) -> (ConstBool [0])
-(NeqPtr (Addr {a} x) (Addr {b} x)) -> (ConstBool [b2i(a != b)])
+(EqPtr (Addr {a} _) (Addr {b} _)) -> (ConstBool [b2i(a == b)])
+(NeqPtr (Addr {a} _) (Addr {b} _)) -> (ConstBool [b2i(a != b)])
+(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)])
+(NeqPtr (OffPtr [o1] p1) (OffPtr [o2] p2)) && isSamePtr(p1, p2) -> (ConstBool [b2i(o1 != o2)])
+(EqPtr (Const(32|64) [c]) (Const(32|64) [d])) -> (ConstBool [b2i(c == d)])
+(NeqPtr (Const(32|64) [c]) (Const(32|64) [d])) -> (ConstBool [b2i(c != d)])
+
+// Simplify address comparisons.
+(EqPtr (AddPtr p1 o1) p2) && isSamePtr(p1, p2) -> (Not (IsNonNil o1))
+(NeqPtr (AddPtr p1 o1) p2) && isSamePtr(p1, p2) -> (IsNonNil o1)
+(EqPtr (Const(32|64) [0]) p) -> (Not (IsNonNil p))
+(NeqPtr (Const(32|64) [0]) p) -> (IsNonNil p)
+(EqPtr (ConstNil) p) -> (Not (IsNonNil p))
+(NeqPtr (ConstNil) p) -> (IsNonNil p)
+
+// Evaluate constant user nil checks.
+(IsNonNil (ConstNil)) -> (ConstBool [0])
+(IsNonNil (Const(32|64) [c])) -> (ConstBool [b2i(c != 0)])
+(IsNonNil (Addr _)) -> (ConstBool [1])
// Inline small runtime.memmove calls with constant length.
(StaticCall {sym} s1:(Store _ (Const64 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem))))
diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go
index add2f0d97b..1d89ec6872 100644
--- a/src/cmd/compile/internal/ssa/rewritegeneric.go
+++ b/src/cmd/compile/internal/ssa/rewritegeneric.go
@@ -114,7 +114,7 @@ func rewriteValuegeneric(v *Value) bool {
case OpEqInter:
return rewriteValuegeneric_OpEqInter_0(v)
case OpEqPtr:
- return rewriteValuegeneric_OpEqPtr_0(v)
+ return rewriteValuegeneric_OpEqPtr_0(v) || rewriteValuegeneric_OpEqPtr_10(v)
case OpEqSlice:
return rewriteValuegeneric_OpEqSlice_0(v)
case OpGeq16:
@@ -298,7 +298,7 @@ func rewriteValuegeneric(v *Value) bool {
case OpNeqInter:
return rewriteValuegeneric_OpNeqInter_0(v)
case OpNeqPtr:
- return rewriteValuegeneric_OpNeqPtr_0(v)
+ return rewriteValuegeneric_OpNeqPtr_0(v) || rewriteValuegeneric_OpNeqPtr_10(v)
case OpNeqSlice:
return rewriteValuegeneric_OpNeqSlice_0(v)
case OpNilCheck:
@@ -10221,33 +10221,280 @@ func rewriteValuegeneric_OpEqInter_0(v *Value) bool {
}
}
func rewriteValuegeneric_OpEqPtr_0(v *Value) bool {
+ // match: (EqPtr x x)
+ // cond:
+ // result: (ConstBool [1])
+ for {
+ _ = v.Args[1]
+ x := v.Args[0]
+ if x != v.Args[1] {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = 1
+ return true
+ }
+ // match: (EqPtr (Addr {a} _) (Addr {b} _))
+ // cond:
+ // result: (ConstBool [b2i(a == b)])
+ 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 != OpAddr {
+ break
+ }
+ b := v_1.Aux
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(a == b)
+ return true
+ }
+ // match: (EqPtr (Addr {b} _) (Addr {a} _))
+ // cond:
+ // result: (ConstBool [b2i(a == b)])
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpAddr {
+ break
+ }
+ b := v_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)
+ return true
+ }
+ // match: (EqPtr (OffPtr [o1] p1) p2)
+ // cond: isSamePtr(p1, p2)
+ // result: (ConstBool [b2i(o1 == 0)])
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpOffPtr {
+ break
+ }
+ o1 := v_0.AuxInt
+ p1 := v_0.Args[0]
+ p2 := v.Args[1]
+ if !(isSamePtr(p1, p2)) {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(o1 == 0)
+ return true
+ }
+ // match: (EqPtr p2 (OffPtr [o1] p1))
+ // cond: isSamePtr(p1, p2)
+ // result: (ConstBool [b2i(o1 == 0)])
+ for {
+ _ = v.Args[1]
+ p2 := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpOffPtr {
+ break
+ }
+ o1 := v_1.AuxInt
+ p1 := v_1.Args[0]
+ if !(isSamePtr(p1, p2)) {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(o1 == 0)
+ return true
+ }
+ // match: (EqPtr (OffPtr [o1] p1) (OffPtr [o2] p2))
+ // cond: isSamePtr(p1, p2)
+ // result: (ConstBool [b2i(o1 == o2)])
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpOffPtr {
+ break
+ }
+ o1 := v_0.AuxInt
+ p1 := v_0.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpOffPtr {
+ break
+ }
+ o2 := v_1.AuxInt
+ p2 := v_1.Args[0]
+ if !(isSamePtr(p1, p2)) {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(o1 == o2)
+ return true
+ }
+ // match: (EqPtr (OffPtr [o2] p2) (OffPtr [o1] p1))
+ // cond: isSamePtr(p1, p2)
+ // result: (ConstBool [b2i(o1 == o2)])
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpOffPtr {
+ break
+ }
+ o2 := v_0.AuxInt
+ p2 := v_0.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpOffPtr {
+ break
+ }
+ o1 := v_1.AuxInt
+ p1 := v_1.Args[0]
+ if !(isSamePtr(p1, p2)) {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(o1 == o2)
+ return true
+ }
+ // match: (EqPtr (Const32 [c]) (Const32 [d]))
+ // cond:
+ // result: (ConstBool [b2i(c == d)])
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst32 {
+ break
+ }
+ c := v_0.AuxInt
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst32 {
+ break
+ }
+ d := v_1.AuxInt
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(c == d)
+ return true
+ }
+ // match: (EqPtr (Const32 [d]) (Const32 [c]))
+ // cond:
+ // result: (ConstBool [b2i(c == d)])
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst32 {
+ break
+ }
+ d := v_0.AuxInt
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst32 {
+ break
+ }
+ c := v_1.AuxInt
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(c == d)
+ return true
+ }
+ // match: (EqPtr (Const64 [c]) (Const64 [d]))
+ // cond:
+ // result: (ConstBool [b2i(c == d)])
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst64 {
+ break
+ }
+ c := v_0.AuxInt
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst64 {
+ break
+ }
+ d := v_1.AuxInt
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(c == d)
+ return true
+ }
+ return false
+}
+func rewriteValuegeneric_OpEqPtr_10(v *Value) bool {
b := v.Block
_ = b
typ := &b.Func.Config.Types
_ = typ
- // match: (EqPtr p (ConstNil))
+ // match: (EqPtr (Const64 [d]) (Const64 [c]))
// cond:
- // result: (Not (IsNonNil p))
+ // result: (ConstBool [b2i(c == d)])
for {
_ = v.Args[1]
- p := v.Args[0]
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst64 {
+ break
+ }
+ d := v_0.AuxInt
v_1 := v.Args[1]
- if v_1.Op != OpConstNil {
+ if v_1.Op != OpConst64 {
+ break
+ }
+ c := v_1.AuxInt
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(c == d)
+ return true
+ }
+ // match: (EqPtr (AddPtr p1 o1) p2)
+ // cond: isSamePtr(p1, p2)
+ // result: (Not (IsNonNil o1))
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpAddPtr {
+ break
+ }
+ _ = v_0.Args[1]
+ p1 := v_0.Args[0]
+ o1 := v_0.Args[1]
+ p2 := v.Args[1]
+ if !(isSamePtr(p1, p2)) {
break
}
v.reset(OpNot)
v0 := b.NewValue0(v.Pos, OpIsNonNil, typ.Bool)
- v0.AddArg(p)
+ v0.AddArg(o1)
v.AddArg(v0)
return true
}
- // match: (EqPtr (ConstNil) p)
+ // match: (EqPtr p2 (AddPtr p1 o1))
+ // cond: isSamePtr(p1, p2)
+ // result: (Not (IsNonNil o1))
+ for {
+ _ = v.Args[1]
+ p2 := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpAddPtr {
+ break
+ }
+ _ = v_1.Args[1]
+ p1 := v_1.Args[0]
+ o1 := v_1.Args[1]
+ if !(isSamePtr(p1, p2)) {
+ break
+ }
+ v.reset(OpNot)
+ v0 := b.NewValue0(v.Pos, OpIsNonNil, typ.Bool)
+ v0.AddArg(o1)
+ v.AddArg(v0)
+ return true
+ }
+ // match: (EqPtr (Const32 [0]) p)
// cond:
// result: (Not (IsNonNil p))
for {
_ = v.Args[1]
v_0 := v.Args[0]
- if v_0.Op != OpConstNil {
+ if v_0.Op != OpConst32 {
+ break
+ }
+ if v_0.AuxInt != 0 {
break
}
p := v.Args[1]
@@ -10257,63 +10504,93 @@ func rewriteValuegeneric_OpEqPtr_0(v *Value) bool {
v.AddArg(v0)
return true
}
- // match: (EqPtr x x)
+ // match: (EqPtr p (Const32 [0]))
// cond:
- // result: (ConstBool [1])
+ // result: (Not (IsNonNil p))
for {
_ = v.Args[1]
- x := v.Args[0]
- if x != v.Args[1] {
+ p := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst32 {
break
}
- v.reset(OpConstBool)
- v.AuxInt = 1
+ if v_1.AuxInt != 0 {
+ break
+ }
+ v.reset(OpNot)
+ v0 := b.NewValue0(v.Pos, OpIsNonNil, typ.Bool)
+ v0.AddArg(p)
+ v.AddArg(v0)
return true
}
- // match: (EqPtr (Addr {a} x) (Addr {b} x))
+ // match: (EqPtr (Const64 [0]) p)
// cond:
- // result: (ConstBool [b2i(a == b)])
+ // result: (Not (IsNonNil p))
for {
_ = v.Args[1]
v_0 := v.Args[0]
- if v_0.Op != OpAddr {
+ if v_0.Op != OpConst64 {
break
}
- a := v_0.Aux
- x := v_0.Args[0]
+ if v_0.AuxInt != 0 {
+ break
+ }
+ p := v.Args[1]
+ v.reset(OpNot)
+ v0 := b.NewValue0(v.Pos, OpIsNonNil, typ.Bool)
+ v0.AddArg(p)
+ v.AddArg(v0)
+ return true
+ }
+ // match: (EqPtr p (Const64 [0]))
+ // cond:
+ // result: (Not (IsNonNil p))
+ for {
+ _ = v.Args[1]
+ p := v.Args[0]
v_1 := v.Args[1]
- if v_1.Op != OpAddr {
+ if v_1.Op != OpConst64 {
break
}
- b := v_1.Aux
- if x != v_1.Args[0] {
+ if v_1.AuxInt != 0 {
break
}
- v.reset(OpConstBool)
- v.AuxInt = b2i(a == b)
+ v.reset(OpNot)
+ v0 := b.NewValue0(v.Pos, OpIsNonNil, typ.Bool)
+ v0.AddArg(p)
+ v.AddArg(v0)
return true
}
- // match: (EqPtr (Addr {b} x) (Addr {a} x))
+ // match: (EqPtr (ConstNil) p)
// cond:
- // result: (ConstBool [b2i(a == b)])
+ // result: (Not (IsNonNil p))
for {
_ = v.Args[1]
v_0 := v.Args[0]
- if v_0.Op != OpAddr {
+ if v_0.Op != OpConstNil {
break
}
- b := v_0.Aux
- x := v_0.Args[0]
+ p := v.Args[1]
+ v.reset(OpNot)
+ v0 := b.NewValue0(v.Pos, OpIsNonNil, typ.Bool)
+ v0.AddArg(p)
+ v.AddArg(v0)
+ return true
+ }
+ // match: (EqPtr p (ConstNil))
+ // cond:
+ // result: (Not (IsNonNil p))
+ for {
+ _ = v.Args[1]
+ p := v.Args[0]
v_1 := v.Args[1]
- if v_1.Op != OpAddr {
- break
- }
- a := v_1.Aux
- if x != v_1.Args[0] {
+ if v_1.Op != OpConstNil {
break
}
- v.reset(OpConstBool)
- v.AuxInt = b2i(a == b)
+ v.reset(OpNot)
+ v0 := b.NewValue0(v.Pos, OpIsNonNil, typ.Bool)
+ v0.AddArg(p)
+ v.AddArg(v0)
return true
}
return false
@@ -11940,6 +12217,44 @@ func rewriteValuegeneric_OpIsNonNil_0(v *Value) bool {
v.AuxInt = 0
return true
}
+ // match: (IsNonNil (Const32 [c]))
+ // cond:
+ // result: (ConstBool [b2i(c != 0)])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst32 {
+ break
+ }
+ c := v_0.AuxInt
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(c != 0)
+ return true
+ }
+ // match: (IsNonNil (Const64 [c]))
+ // cond:
+ // result: (ConstBool [b2i(c != 0)])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst64 {
+ break
+ }
+ c := v_0.AuxInt
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(c != 0)
+ return true
+ }
+ // match: (IsNonNil (Addr _))
+ // cond:
+ // result: (ConstBool [1])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpAddr {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = 1
+ return true
+ }
return false
}
func rewriteValuegeneric_OpIsSliceInBounds_0(v *Value) bool {
@@ -18020,27 +18335,272 @@ func rewriteValuegeneric_OpNeqInter_0(v *Value) bool {
}
}
func rewriteValuegeneric_OpNeqPtr_0(v *Value) bool {
- // match: (NeqPtr p (ConstNil))
+ // match: (NeqPtr x x)
// cond:
- // result: (IsNonNil p)
+ // result: (ConstBool [0])
for {
_ = v.Args[1]
- p := v.Args[0]
+ x := v.Args[0]
+ if x != v.Args[1] {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = 0
+ return true
+ }
+ // match: (NeqPtr (Addr {a} _) (Addr {b} _))
+ // cond:
+ // result: (ConstBool [b2i(a != b)])
+ 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 != OpConstNil {
+ if v_1.Op != OpAddr {
+ break
+ }
+ b := v_1.Aux
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(a != b)
+ return true
+ }
+ // match: (NeqPtr (Addr {b} _) (Addr {a} _))
+ // cond:
+ // result: (ConstBool [b2i(a != b)])
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpAddr {
+ break
+ }
+ b := v_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)
+ return true
+ }
+ // match: (NeqPtr (OffPtr [o1] p1) p2)
+ // cond: isSamePtr(p1, p2)
+ // result: (ConstBool [b2i(o1 != 0)])
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpOffPtr {
+ break
+ }
+ o1 := v_0.AuxInt
+ p1 := v_0.Args[0]
+ p2 := v.Args[1]
+ if !(isSamePtr(p1, p2)) {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(o1 != 0)
+ return true
+ }
+ // match: (NeqPtr p2 (OffPtr [o1] p1))
+ // cond: isSamePtr(p1, p2)
+ // result: (ConstBool [b2i(o1 != 0)])
+ for {
+ _ = v.Args[1]
+ p2 := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpOffPtr {
+ break
+ }
+ o1 := v_1.AuxInt
+ p1 := v_1.Args[0]
+ if !(isSamePtr(p1, p2)) {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(o1 != 0)
+ return true
+ }
+ // match: (NeqPtr (OffPtr [o1] p1) (OffPtr [o2] p2))
+ // cond: isSamePtr(p1, p2)
+ // result: (ConstBool [b2i(o1 != o2)])
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpOffPtr {
+ break
+ }
+ o1 := v_0.AuxInt
+ p1 := v_0.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpOffPtr {
+ break
+ }
+ o2 := v_1.AuxInt
+ p2 := v_1.Args[0]
+ if !(isSamePtr(p1, p2)) {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(o1 != o2)
+ return true
+ }
+ // match: (NeqPtr (OffPtr [o2] p2) (OffPtr [o1] p1))
+ // cond: isSamePtr(p1, p2)
+ // result: (ConstBool [b2i(o1 != o2)])
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpOffPtr {
+ break
+ }
+ o2 := v_0.AuxInt
+ p2 := v_0.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpOffPtr {
+ break
+ }
+ o1 := v_1.AuxInt
+ p1 := v_1.Args[0]
+ if !(isSamePtr(p1, p2)) {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(o1 != o2)
+ return true
+ }
+ // match: (NeqPtr (Const32 [c]) (Const32 [d]))
+ // cond:
+ // result: (ConstBool [b2i(c != d)])
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst32 {
+ break
+ }
+ c := v_0.AuxInt
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst32 {
+ break
+ }
+ d := v_1.AuxInt
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(c != d)
+ return true
+ }
+ // match: (NeqPtr (Const32 [d]) (Const32 [c]))
+ // cond:
+ // result: (ConstBool [b2i(c != d)])
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst32 {
+ break
+ }
+ d := v_0.AuxInt
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst32 {
+ break
+ }
+ c := v_1.AuxInt
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(c != d)
+ return true
+ }
+ // match: (NeqPtr (Const64 [c]) (Const64 [d]))
+ // cond:
+ // result: (ConstBool [b2i(c != d)])
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst64 {
+ break
+ }
+ c := v_0.AuxInt
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst64 {
+ break
+ }
+ d := v_1.AuxInt
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(c != d)
+ return true
+ }
+ return false
+}
+func rewriteValuegeneric_OpNeqPtr_10(v *Value) bool {
+ // match: (NeqPtr (Const64 [d]) (Const64 [c]))
+ // cond:
+ // result: (ConstBool [b2i(c != d)])
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpConst64 {
+ break
+ }
+ d := v_0.AuxInt
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst64 {
+ break
+ }
+ c := v_1.AuxInt
+ v.reset(OpConstBool)
+ v.AuxInt = b2i(c != d)
+ return true
+ }
+ // match: (NeqPtr (AddPtr p1 o1) p2)
+ // cond: isSamePtr(p1, p2)
+ // result: (IsNonNil o1)
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpAddPtr {
+ break
+ }
+ _ = v_0.Args[1]
+ p1 := v_0.Args[0]
+ o1 := v_0.Args[1]
+ p2 := v.Args[1]
+ if !(isSamePtr(p1, p2)) {
break
}
v.reset(OpIsNonNil)
- v.AddArg(p)
+ v.AddArg(o1)
return true
}
- // match: (NeqPtr (ConstNil) p)
+ // match: (NeqPtr p2 (AddPtr p1 o1))
+ // cond: isSamePtr(p1, p2)
+ // result: (IsNonNil o1)
+ for {
+ _ = v.Args[1]
+ p2 := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpAddPtr {
+ break
+ }
+ _ = v_1.Args[1]
+ p1 := v_1.Args[0]
+ o1 := v_1.Args[1]
+ if !(isSamePtr(p1, p2)) {
+ break
+ }
+ v.reset(OpIsNonNil)
+ v.AddArg(o1)
+ return true
+ }
+ // match: (NeqPtr (Const32 [0]) p)
// cond:
// result: (IsNonNil p)
for {
_ = v.Args[1]
v_0 := v.Args[0]
- if v_0.Op != OpConstNil {
+ if v_0.Op != OpConst32 {
+ break
+ }
+ if v_0.AuxInt != 0 {
break
}
p := v.Args[1]
@@ -18048,63 +18608,83 @@ func rewriteValuegeneric_OpNeqPtr_0(v *Value) bool {
v.AddArg(p)
return true
}
- // match: (NeqPtr x x)
+ // match: (NeqPtr p (Const32 [0]))
// cond:
- // result: (ConstBool [0])
+ // result: (IsNonNil p)
for {
_ = v.Args[1]
- x := v.Args[0]
- if x != v.Args[1] {
+ p := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst32 {
break
}
- v.reset(OpConstBool)
- v.AuxInt = 0
+ if v_1.AuxInt != 0 {
+ break
+ }
+ v.reset(OpIsNonNil)
+ v.AddArg(p)
return true
}
- // match: (NeqPtr (Addr {a} x) (Addr {b} x))
+ // match: (NeqPtr (Const64 [0]) p)
// cond:
- // result: (ConstBool [b2i(a != b)])
+ // result: (IsNonNil p)
for {
_ = v.Args[1]
v_0 := v.Args[0]
- if v_0.Op != OpAddr {
+ if v_0.Op != OpConst64 {
break
}
- a := v_0.Aux
- x := v_0.Args[0]
+ if v_0.AuxInt != 0 {
+ break
+ }
+ p := v.Args[1]
+ v.reset(OpIsNonNil)
+ v.AddArg(p)
+ return true
+ }
+ // match: (NeqPtr p (Const64 [0]))
+ // cond:
+ // result: (IsNonNil p)
+ for {
+ _ = v.Args[1]
+ p := v.Args[0]
v_1 := v.Args[1]
- if v_1.Op != OpAddr {
+ if v_1.Op != OpConst64 {
break
}
- b := v_1.Aux
- if x != v_1.Args[0] {
+ if v_1.AuxInt != 0 {
break
}
- v.reset(OpConstBool)
- v.AuxInt = b2i(a != b)
+ v.reset(OpIsNonNil)
+ v.AddArg(p)
return true
}
- // match: (NeqPtr (Addr {b} x) (Addr {a} x))
+ // match: (NeqPtr (ConstNil) p)
// cond:
- // result: (ConstBool [b2i(a != b)])
+ // result: (IsNonNil p)
for {
_ = v.Args[1]
v_0 := v.Args[0]
- if v_0.Op != OpAddr {
+ if v_0.Op != OpConstNil {
break
}
- b := v_0.Aux
- x := v_0.Args[0]
+ p := v.Args[1]
+ v.reset(OpIsNonNil)
+ v.AddArg(p)
+ return true
+ }
+ // match: (NeqPtr p (ConstNil))
+ // cond:
+ // result: (IsNonNil p)
+ for {
+ _ = v.Args[1]
+ p := v.Args[0]
v_1 := v.Args[1]
- if v_1.Op != OpAddr {
- break
- }
- a := v_1.Aux
- if x != v_1.Args[0] {
+ if v_1.Op != OpConstNil {
break
}
- v.reset(OpConstBool)
- v.AuxInt = b2i(a != b)
+ v.reset(OpIsNonNil)
+ v.AddArg(p)
return true
}
return false