mirror of
https://github.com/golang/go.git
synced 2025-05-05 23:53:05 +00:00
cmd/compile: avoid memmove -> SSA move rewrite when size is negative
We should panic in this situation. Rewriting to a SSA op just leads to a compiler panic. Fixes #36259 Change-Id: I6e0bccbed7dd0fdac7ebae76b98a211947947386 Reviewed-on: https://go-review.googlesource.com/c/go/+/212405 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
parent
e092fc352a
commit
bc98e35b53
@ -1938,6 +1938,7 @@
|
|||||||
|
|
||||||
// Inline small or disjoint runtime.memmove calls with constant length.
|
// Inline small or disjoint runtime.memmove calls with constant length.
|
||||||
(StaticCall {sym} s1:(Store _ (Const(64|32) [sz]) s2:(Store _ src s3:(Store {t} _ dst mem))))
|
(StaticCall {sym} s1:(Store _ (Const(64|32) [sz]) s2:(Store _ src s3:(Store {t} _ dst mem))))
|
||||||
|
&& sz >= 0
|
||||||
&& isSameSym(sym,"runtime.memmove")
|
&& isSameSym(sym,"runtime.memmove")
|
||||||
&& t.(*types.Type).IsPtr() // avoids TUINTPTR, see issue 30061
|
&& t.(*types.Type).IsPtr() // avoids TUINTPTR, see issue 30061
|
||||||
&& s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
|
&& s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
|
||||||
|
@ -19680,7 +19680,7 @@ func rewriteValuegeneric_OpStaticCall(v *Value) bool {
|
|||||||
b := v.Block
|
b := v.Block
|
||||||
config := b.Func.Config
|
config := b.Func.Config
|
||||||
// match: (StaticCall {sym} s1:(Store _ (Const64 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem))))
|
// match: (StaticCall {sym} s1:(Store _ (Const64 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem))))
|
||||||
// cond: isSameSym(sym,"runtime.memmove") && t.(*types.Type).IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst,src,sz,config) && clobber(s1) && clobber(s2) && clobber(s3)
|
// cond: sz >= 0 && isSameSym(sym,"runtime.memmove") && t.(*types.Type).IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst,src,sz,config) && clobber(s1) && clobber(s2) && clobber(s3)
|
||||||
// result: (Move {t.(*types.Type).Elem()} [sz] dst src mem)
|
// result: (Move {t.(*types.Type).Elem()} [sz] dst src mem)
|
||||||
for {
|
for {
|
||||||
sym := v.Aux
|
sym := v.Aux
|
||||||
@ -19707,7 +19707,7 @@ func rewriteValuegeneric_OpStaticCall(v *Value) bool {
|
|||||||
t := s3.Aux
|
t := s3.Aux
|
||||||
mem := s3.Args[2]
|
mem := s3.Args[2]
|
||||||
dst := s3.Args[1]
|
dst := s3.Args[1]
|
||||||
if !(isSameSym(sym, "runtime.memmove") && t.(*types.Type).IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(s1) && clobber(s2) && clobber(s3)) {
|
if !(sz >= 0 && isSameSym(sym, "runtime.memmove") && t.(*types.Type).IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(s1) && clobber(s2) && clobber(s3)) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
v.reset(OpMove)
|
v.reset(OpMove)
|
||||||
@ -19719,7 +19719,7 @@ func rewriteValuegeneric_OpStaticCall(v *Value) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (StaticCall {sym} s1:(Store _ (Const32 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem))))
|
// match: (StaticCall {sym} s1:(Store _ (Const32 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem))))
|
||||||
// cond: isSameSym(sym,"runtime.memmove") && t.(*types.Type).IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst,src,sz,config) && clobber(s1) && clobber(s2) && clobber(s3)
|
// cond: sz >= 0 && isSameSym(sym,"runtime.memmove") && t.(*types.Type).IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst,src,sz,config) && clobber(s1) && clobber(s2) && clobber(s3)
|
||||||
// result: (Move {t.(*types.Type).Elem()} [sz] dst src mem)
|
// result: (Move {t.(*types.Type).Elem()} [sz] dst src mem)
|
||||||
for {
|
for {
|
||||||
sym := v.Aux
|
sym := v.Aux
|
||||||
@ -19746,7 +19746,7 @@ func rewriteValuegeneric_OpStaticCall(v *Value) bool {
|
|||||||
t := s3.Aux
|
t := s3.Aux
|
||||||
mem := s3.Args[2]
|
mem := s3.Args[2]
|
||||||
dst := s3.Args[1]
|
dst := s3.Args[1]
|
||||||
if !(isSameSym(sym, "runtime.memmove") && t.(*types.Type).IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(s1) && clobber(s2) && clobber(s3)) {
|
if !(sz >= 0 && isSameSym(sym, "runtime.memmove") && t.(*types.Type).IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(s1) && clobber(s2) && clobber(s3)) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
v.reset(OpMove)
|
v.reset(OpMove)
|
||||||
|
28
test/fixedbugs/issue36259.go
Normal file
28
test/fixedbugs/issue36259.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// 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 main
|
||||||
|
|
||||||
|
func rotate(s []int, m int) {
|
||||||
|
l := len(s)
|
||||||
|
m = m % l
|
||||||
|
buf := make([]int, m)
|
||||||
|
|
||||||
|
copy(buf, s)
|
||||||
|
copy(s, s[m:])
|
||||||
|
copy(s[l-m:], buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
a0 := [...]int{1,2,3,4,5}
|
||||||
|
println(a0[0])
|
||||||
|
|
||||||
|
rotate(a0[:], 1)
|
||||||
|
println(a0[0])
|
||||||
|
|
||||||
|
rotate(a0[:], -3)
|
||||||
|
println(a0[0])
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user