mirror of
https://github.com/golang/go
synced 2024-09-04 23:44:16 +00:00
cmd/compile: force folding of MOVDaddr into storezero
Fold MOVDaddr ops into MOVXstorezero ops. Also fold ADDconst into MOVDaddr so we're sure there isn't (MOVDstorezero (ADDconst (MOVDaddr ..))) Without this CL, we get: v1 = MOVDaddr {s} v2 = VARDEF {s} v3 = MOVDstorezero v1 v2 The liveness pass thinks the MOVDaddr is a read of s, so s is incorrectly thought to be live at the start of the function. Fixes #17194 Change-Id: I2b4a2f13b12aa5b072941ee1c7b89f3793650cdc Reviewed-on: https://go-review.googlesource.com/30086 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com> Reviewed-by: Michael Munday <munday@ca.ibm.com>
This commit is contained in:
parent
7d0642d9d6
commit
6300161d40
|
@ -523,6 +523,7 @@
|
|||
(ADD (MOVDconst [c]) x) && is32Bit(c) -> (ADDconst [c] x)
|
||||
(ADD x (MOVDconst [c])) && is32Bit(c) -> (ADDconst [c] x)
|
||||
(ADDconst [c] (ADDconst [d] x)) && is32Bit(c+d) -> (ADDconst [c+d] x)
|
||||
(ADDconst [c] (MOVDaddr [d] {sym} x)) -> (MOVDaddr [c+d] {sym} x)
|
||||
(ADDconst [0] x) -> x
|
||||
(ANDconst [-1] x) -> x
|
||||
(ANDconst [0] _) -> (MOVDconst [0])
|
||||
|
@ -600,6 +601,16 @@
|
|||
(MOVBstorezero [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(off1+off2) ->
|
||||
(MOVBstorezero [off1+off2] {sym} x mem)
|
||||
|
||||
// Fold symbols into storezero
|
||||
(MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) ->
|
||||
(MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
|
||||
(MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) ->
|
||||
(MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
|
||||
(MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) ->
|
||||
(MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
|
||||
(MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) ->
|
||||
(MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
|
||||
|
||||
// Lowering extension
|
||||
// Note: we always extend to 64 bits even though some ops don't need that many result bits.
|
||||
(SignExt8to16 x) -> (MOVBreg x)
|
||||
|
|
|
@ -4101,6 +4101,24 @@ func rewriteValuePPC64_OpPPC64ADDconst(v *Value, config *Config) bool {
|
|||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (ADDconst [c] (MOVDaddr [d] {sym} x))
|
||||
// cond:
|
||||
// result: (MOVDaddr [c+d] {sym} x)
|
||||
for {
|
||||
c := v.AuxInt
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64MOVDaddr {
|
||||
break
|
||||
}
|
||||
d := v_0.AuxInt
|
||||
sym := v_0.Aux
|
||||
x := v_0.Args[0]
|
||||
v.reset(OpPPC64MOVDaddr)
|
||||
v.AuxInt = c + d
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (ADDconst [0] x)
|
||||
// cond:
|
||||
// result: x
|
||||
|
@ -5263,6 +5281,30 @@ func rewriteValuePPC64_OpPPC64MOVBstorezero(v *Value, config *Config) bool {
|
|||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem)
|
||||
// cond: canMergeSym(sym1,sym2)
|
||||
// result: (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym1 := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64MOVDaddr {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
sym2 := v_0.Aux
|
||||
x := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVBstorezero)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = mergeSym(sym1, sym2)
|
||||
v.AddArg(x)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVDload(v *Value, config *Config) bool {
|
||||
|
@ -5422,6 +5464,30 @@ func rewriteValuePPC64_OpPPC64MOVDstorezero(v *Value, config *Config) bool {
|
|||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem)
|
||||
// cond: canMergeSym(sym1,sym2)
|
||||
// result: (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym1 := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64MOVDaddr {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
sym2 := v_0.Aux
|
||||
x := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVDstorezero)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = mergeSym(sym1, sym2)
|
||||
v.AddArg(x)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVHZload(v *Value, config *Config) bool {
|
||||
|
@ -5737,6 +5803,30 @@ func rewriteValuePPC64_OpPPC64MOVHstorezero(v *Value, config *Config) bool {
|
|||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem)
|
||||
// cond: canMergeSym(sym1,sym2)
|
||||
// result: (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym1 := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64MOVDaddr {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
sym2 := v_0.Aux
|
||||
x := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVHstorezero)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = mergeSym(sym1, sym2)
|
||||
v.AddArg(x)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVWZload(v *Value, config *Config) bool {
|
||||
|
@ -5948,6 +6038,30 @@ func rewriteValuePPC64_OpPPC64MOVWstorezero(v *Value, config *Config) bool {
|
|||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem)
|
||||
// cond: canMergeSym(sym1,sym2)
|
||||
// result: (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym1 := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64MOVDaddr {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
sym2 := v_0.Aux
|
||||
x := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVWstorezero)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = mergeSym(sym1, sym2)
|
||||
v.AddArg(x)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64NotEqual(v *Value, config *Config) bool {
|
||||
|
|
17
test/fixedbugs/issue17194.go
Normal file
17
test/fixedbugs/issue17194.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
// compile
|
||||
|
||||
// Copyright 2016 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 foo
|
||||
|
||||
func f(x []interface{}) (err error) {
|
||||
for _, d := range x {
|
||||
_, ok := d.(*int)
|
||||
if ok {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
Loading…
Reference in a new issue