mirror of https://github.com/golang/go.git
cmd/compile: optimize s==s for strings
s==s is always true for strings. This comes up in NaN testing in generic code, where we want x==x to compile completely away except for float types. Fixes #60777 Change-Id: I3ce054b5121354de2f9751b010fb409f148cb637 Reviewed-on: https://go-review.googlesource.com/c/go/+/503795 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Keith Randall <khr@golang.org>
This commit is contained in:
parent
f0894a00f4
commit
d0964e172b
|
|
@ -2121,6 +2121,11 @@
|
|||
&& isSameCall(callAux, "runtime.memequal")
|
||||
=> (MakeResult (ConstBool <typ.Bool> [true]) mem)
|
||||
|
||||
(Static(Call|LECall) {callAux} p q _ mem)
|
||||
&& isSameCall(callAux, "runtime.memequal")
|
||||
&& isSamePtr(p, q)
|
||||
=> (MakeResult (ConstBool <typ.Bool> [true]) mem)
|
||||
|
||||
// Turn known-size calls to memclrNoHeapPointers into a Zero.
|
||||
// Note that we are using types.Types[types.TUINT8] instead of sptr.Type.Elem() - see issue 55122 and CL 431496 for more details.
|
||||
(SelectN [0] call:(StaticCall {sym} sptr (Const(64|32) [c]) mem))
|
||||
|
|
|
|||
|
|
@ -397,6 +397,8 @@ func rewriteValuegeneric(v *Value) bool {
|
|||
return rewriteValuegeneric_OpSlicemask(v)
|
||||
case OpSqrt:
|
||||
return rewriteValuegeneric_OpSqrt(v)
|
||||
case OpStaticCall:
|
||||
return rewriteValuegeneric_OpStaticCall(v)
|
||||
case OpStaticLECall:
|
||||
return rewriteValuegeneric_OpStaticLECall(v)
|
||||
case OpStore:
|
||||
|
|
@ -28219,6 +28221,31 @@ func rewriteValuegeneric_OpSqrt(v *Value) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpStaticCall(v *Value) bool {
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (StaticCall {callAux} p q _ mem)
|
||||
// cond: isSameCall(callAux, "runtime.memequal") && isSamePtr(p, q)
|
||||
// result: (MakeResult (ConstBool <typ.Bool> [true]) mem)
|
||||
for {
|
||||
if len(v.Args) != 4 {
|
||||
break
|
||||
}
|
||||
callAux := auxToCall(v.Aux)
|
||||
mem := v.Args[3]
|
||||
p := v.Args[0]
|
||||
q := v.Args[1]
|
||||
if !(isSameCall(callAux, "runtime.memequal") && isSamePtr(p, q)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpMakeResult)
|
||||
v0 := b.NewValue0(v.Pos, OpConstBool, typ.Bool)
|
||||
v0.AuxInt = boolToAuxInt(true)
|
||||
v.AddArg2(v0, mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpStaticLECall(v *Value) bool {
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
|
|
@ -28506,6 +28533,26 @@ func rewriteValuegeneric_OpStaticLECall(v *Value) bool {
|
|||
v.AddArg2(v0, mem)
|
||||
return true
|
||||
}
|
||||
// match: (StaticLECall {callAux} p q _ mem)
|
||||
// cond: isSameCall(callAux, "runtime.memequal") && isSamePtr(p, q)
|
||||
// result: (MakeResult (ConstBool <typ.Bool> [true]) mem)
|
||||
for {
|
||||
if len(v.Args) != 4 {
|
||||
break
|
||||
}
|
||||
callAux := auxToCall(v.Aux)
|
||||
mem := v.Args[3]
|
||||
p := v.Args[0]
|
||||
q := v.Args[1]
|
||||
if !(isSameCall(callAux, "runtime.memequal") && isSamePtr(p, q)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpMakeResult)
|
||||
v0 := b.NewValue0(v.Pos, OpConstBool, typ.Bool)
|
||||
v0.AuxInt = boolToAuxInt(true)
|
||||
v.AddArg2(v0, mem)
|
||||
return true
|
||||
}
|
||||
// match: (StaticLECall {callAux} _ (Const64 [0]) (Const64 [0]) mem)
|
||||
// cond: isSameCall(callAux, "runtime.makeslice")
|
||||
// result: (MakeResult (Addr <v.Type.FieldType(0)> {ir.Syms.Zerobase} (SB)) mem)
|
||||
|
|
|
|||
|
|
@ -67,4 +67,14 @@ func ConstantLoad() {
|
|||
bsink = []byte("0123456789ab")
|
||||
}
|
||||
|
||||
// self-equality is always true. See issue 60777.
|
||||
func EqualSelf(s string) bool {
|
||||
// amd64:`MOVL\t\$1, AX`,-`.*memequal.*`
|
||||
return s == s
|
||||
}
|
||||
func NotEqualSelf(s string) bool {
|
||||
// amd64:`XORL\tAX, AX`,-`.*memequal.*`
|
||||
return s != s
|
||||
}
|
||||
|
||||
var bsink []byte
|
||||
|
|
|
|||
Loading…
Reference in New Issue