aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJorropo <jorropo.pgm@gmail.com>2023-01-31 19:10:33 +0100
committerKeith Randall <khr@golang.org>2023-02-08 22:31:12 +0000
commit0d8d181bd575dca359266a1008b436b50db8ba18 (patch)
tree204602f63057688631357d7ddc492597e0870384
parent9d81ccbf51b08bb29efad5fa9acc8fa69bbd8f6b (diff)
downloadgo-0d8d181bd575dca359266a1008b436b50db8ba18.tar.xz
cmd/compile: use MakeResult in empty MakeSlice elimination
This gets eliminated by thoses rules above: // for rewriting results of some late-expanded rewrites (below) (SelectN [0] (MakeResult x ___)) => x (SelectN [1] (MakeResult x y ___)) => y (SelectN [2] (MakeResult x y z ___)) => z Fixes #58161 Change-Id: I4fbfd52c72c06b6b3db906bd9910b6dbb7fe8975 Reviewed-on: https://go-review.googlesource.com/c/go/+/463846 Reviewed-by: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com>
-rw-r--r--src/cmd/compile/internal/ssa/_gen/generic.rules12
-rw-r--r--src/cmd/compile/internal/ssa/rewritegeneric.go149
-rw-r--r--test/fixedbugs/issue58161.go15
3 files changed, 68 insertions, 108 deletions
diff --git a/src/cmd/compile/internal/ssa/_gen/generic.rules b/src/cmd/compile/internal/ssa/_gen/generic.rules
index 0cbde1ee45..10da571988 100644
--- a/src/cmd/compile/internal/ssa/_gen/generic.rules
+++ b/src/cmd/compile/internal/ssa/_gen/generic.rules
@@ -2077,15 +2077,9 @@
=> (Zero {types.Types[types.TUINT8]} [int64(c)] sptr mem)
// Recognise make([]T, 0) and replace it with a pointer to the zerobase
-(SelectN [0] call:(StaticLECall _ (Const(64|32) [0]) (Const(64|32) [0]) _))
- && isSameCall(call.Aux, "runtime.makeslice")
- && clobberIfDead(call)
- => (Addr {ir.Syms.Zerobase} (SB))
-
-(SelectN [1] call:(StaticLECall _ (Const(64|32) [0]) (Const(64|32) [0]) mem))
- && isSameCall(call.Aux, "runtime.makeslice")
- && clobberIfDead(call)
- => mem
+(StaticLECall {callAux} _ (Const(64|32) [0]) (Const(64|32) [0]) mem)
+ && isSameCall(callAux, "runtime.makeslice")
+ => (MakeResult (Addr <v.Type.FieldType(0)> {ir.Syms.Zerobase} (SB)) mem)
// Evaluate constant address comparisons.
(EqPtr x x) => (ConstBool [true])
diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go
index 5917d45505..b81d093119 100644
--- a/src/cmd/compile/internal/ssa/rewritegeneric.go
+++ b/src/cmd/compile/internal/ssa/rewritegeneric.go
@@ -26380,7 +26380,6 @@ func rewriteValuegeneric_OpSelectN(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
- typ := &b.Func.Config.Types
// match: (SelectN [0] (MakeResult x ___))
// result: x
for {
@@ -26467,104 +26466,6 @@ func rewriteValuegeneric_OpSelectN(v *Value) bool {
v.AddArg2(sptr, mem)
return true
}
- // match: (SelectN [0] call:(StaticLECall _ (Const64 [0]) (Const64 [0]) _))
- // cond: isSameCall(call.Aux, "runtime.makeslice") && clobberIfDead(call)
- // result: (Addr {ir.Syms.Zerobase} (SB))
- for {
- if auxIntToInt64(v.AuxInt) != 0 {
- break
- }
- call := v_0
- if call.Op != OpStaticLECall || len(call.Args) != 4 {
- break
- }
- _ = call.Args[2]
- call_1 := call.Args[1]
- if call_1.Op != OpConst64 || auxIntToInt64(call_1.AuxInt) != 0 {
- break
- }
- call_2 := call.Args[2]
- if call_2.Op != OpConst64 || auxIntToInt64(call_2.AuxInt) != 0 || !(isSameCall(call.Aux, "runtime.makeslice") && clobberIfDead(call)) {
- break
- }
- v.reset(OpAddr)
- v.Aux = symToAux(ir.Syms.Zerobase)
- v0 := b.NewValue0(v.Pos, OpSB, typ.Uintptr)
- v.AddArg(v0)
- return true
- }
- // match: (SelectN [0] call:(StaticLECall _ (Const32 [0]) (Const32 [0]) _))
- // cond: isSameCall(call.Aux, "runtime.makeslice") && clobberIfDead(call)
- // result: (Addr {ir.Syms.Zerobase} (SB))
- for {
- if auxIntToInt64(v.AuxInt) != 0 {
- break
- }
- call := v_0
- if call.Op != OpStaticLECall || len(call.Args) != 4 {
- break
- }
- _ = call.Args[2]
- call_1 := call.Args[1]
- if call_1.Op != OpConst32 || auxIntToInt32(call_1.AuxInt) != 0 {
- break
- }
- call_2 := call.Args[2]
- if call_2.Op != OpConst32 || auxIntToInt32(call_2.AuxInt) != 0 || !(isSameCall(call.Aux, "runtime.makeslice") && clobberIfDead(call)) {
- break
- }
- v.reset(OpAddr)
- v.Aux = symToAux(ir.Syms.Zerobase)
- v0 := b.NewValue0(v.Pos, OpSB, typ.Uintptr)
- v.AddArg(v0)
- return true
- }
- // match: (SelectN [1] call:(StaticLECall _ (Const64 [0]) (Const64 [0]) mem))
- // cond: isSameCall(call.Aux, "runtime.makeslice") && clobberIfDead(call)
- // result: mem
- for {
- if auxIntToInt64(v.AuxInt) != 1 {
- break
- }
- call := v_0
- if call.Op != OpStaticLECall || len(call.Args) != 4 {
- break
- }
- mem := call.Args[3]
- call_1 := call.Args[1]
- if call_1.Op != OpConst64 || auxIntToInt64(call_1.AuxInt) != 0 {
- break
- }
- call_2 := call.Args[2]
- if call_2.Op != OpConst64 || auxIntToInt64(call_2.AuxInt) != 0 || !(isSameCall(call.Aux, "runtime.makeslice") && clobberIfDead(call)) {
- break
- }
- v.copyOf(mem)
- return true
- }
- // match: (SelectN [1] call:(StaticLECall _ (Const32 [0]) (Const32 [0]) mem))
- // cond: isSameCall(call.Aux, "runtime.makeslice") && clobberIfDead(call)
- // result: mem
- for {
- if auxIntToInt64(v.AuxInt) != 1 {
- break
- }
- call := v_0
- if call.Op != OpStaticLECall || len(call.Args) != 4 {
- break
- }
- mem := call.Args[3]
- call_1 := call.Args[1]
- if call_1.Op != OpConst32 || auxIntToInt32(call_1.AuxInt) != 0 {
- break
- }
- call_2 := call.Args[2]
- if call_2.Op != OpConst32 || auxIntToInt32(call_2.AuxInt) != 0 || !(isSameCall(call.Aux, "runtime.makeslice") && clobberIfDead(call)) {
- break
- }
- v.copyOf(mem)
- return true
- }
// match: (SelectN [0] call:(StaticCall {sym} s1:(Store _ (Const64 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem)))))
// cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3, call)
// result: (Move {types.Types[types.TUINT8]} [int64(sz)] dst src mem)
@@ -27463,6 +27364,56 @@ func rewriteValuegeneric_OpStaticLECall(v *Value) bool {
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)
+ for {
+ if len(v.Args) != 4 {
+ break
+ }
+ callAux := auxToCall(v.Aux)
+ mem := v.Args[3]
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != 0 {
+ break
+ }
+ v_2 := v.Args[2]
+ if v_2.Op != OpConst64 || auxIntToInt64(v_2.AuxInt) != 0 || !(isSameCall(callAux, "runtime.makeslice")) {
+ break
+ }
+ v.reset(OpMakeResult)
+ v0 := b.NewValue0(v.Pos, OpAddr, v.Type.FieldType(0))
+ v0.Aux = symToAux(ir.Syms.Zerobase)
+ v1 := b.NewValue0(v.Pos, OpSB, typ.Uintptr)
+ v0.AddArg(v1)
+ v.AddArg2(v0, mem)
+ return true
+ }
+ // match: (StaticLECall {callAux} _ (Const32 [0]) (Const32 [0]) mem)
+ // cond: isSameCall(callAux, "runtime.makeslice")
+ // result: (MakeResult (Addr <v.Type.FieldType(0)> {ir.Syms.Zerobase} (SB)) mem)
+ for {
+ if len(v.Args) != 4 {
+ break
+ }
+ callAux := auxToCall(v.Aux)
+ mem := v.Args[3]
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst32 || auxIntToInt32(v_1.AuxInt) != 0 {
+ break
+ }
+ v_2 := v.Args[2]
+ if v_2.Op != OpConst32 || auxIntToInt32(v_2.AuxInt) != 0 || !(isSameCall(callAux, "runtime.makeslice")) {
+ break
+ }
+ v.reset(OpMakeResult)
+ v0 := b.NewValue0(v.Pos, OpAddr, v.Type.FieldType(0))
+ v0.Aux = symToAux(ir.Syms.Zerobase)
+ v1 := b.NewValue0(v.Pos, OpSB, typ.Uintptr)
+ v0.AddArg(v1)
+ v.AddArg2(v0, mem)
+ return true
+ }
return false
}
func rewriteValuegeneric_OpStore(v *Value) bool {
diff --git a/test/fixedbugs/issue58161.go b/test/fixedbugs/issue58161.go
new file mode 100644
index 0000000000..33113f6563
--- /dev/null
+++ b/test/fixedbugs/issue58161.go
@@ -0,0 +1,15 @@
+// compile -d=ssa/check/seed=1
+
+// Copyright 2023 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 main
+
+func F[G int]() int {
+ return len(make([]int, copy([]G{}, []G{})))
+}
+
+func main() {
+ F[int]()
+}