From b8cbcacabe4fecab9122e04cdc71e7f2649e9981 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Thu, 6 Jun 2019 11:40:47 -0700 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- .../compile/internal/ssa/gen/generic.rules | 14 + .../compile/internal/ssa/rewritegeneric.go | 762 +++++++++++++++++- test/fixedbugs/issue32454.go | 23 + 3 files changed, 781 insertions(+), 18 deletions(-) create mode 100644 test/fixedbugs/issue32454.go diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules index 8f2ff28879..089acc38a1 100644 --- a/src/cmd/compile/internal/ssa/gen/generic.rules +++ b/src/cmd/compile/internal/ssa/gen/generic.rules @@ -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)) diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go index e3a123e1d2..d25a62e36c 100644 --- a/src/cmd/compile/internal/ssa/rewritegeneric.go +++ b/src/cmd/compile/internal/ssa/rewritegeneric.go @@ -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) diff --git a/test/fixedbugs/issue32454.go b/test/fixedbugs/issue32454.go new file mode 100644 index 0000000000..70895c97fa --- /dev/null +++ b/test/fixedbugs/issue32454.go @@ -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 + } + } +} -- 2.48.1