mirror of
https://github.com/golang/go
synced 2024-11-23 00:30:07 -07:00
cmd/compile/internal/ssa: remove useless zero extension
We generate MOVBLZX for byte-sized LoadReg, so (MOVBQZX (LoadReg (Arg))) is the same as (LoadReg (Arg)). Remove those zero extension where possible. Triggers several times during all.bash. Fixes #25378 Updates #15300 Change-Id: If50656e66f217832a13ee8f49c47997f4fcc093a Reviewed-on: https://go-review.googlesource.com/115617 Run-TryBot: Ilya Tocar <ilya.tocar@intel.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
c292b32f33
commit
a3593685cf
@ -988,6 +988,8 @@
|
||||
(MOVLQZX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVLload <v.Type> [off] {sym} ptr mem)
|
||||
|
||||
(MOVLQZX x) && zeroUpper32Bits(x,3) -> x
|
||||
(MOVWQZX x) && zeroUpper48Bits(x,3) -> x
|
||||
(MOVBQZX x) && zeroUpper56Bits(x,3) -> x
|
||||
|
||||
(MOVBQZX x:(MOVBloadidx1 [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx1 <v.Type> [off] {sym} ptr idx mem)
|
||||
(MOVWQZX x:(MOVWloadidx1 [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx1 <v.Type> [off] {sym} ptr idx mem)
|
||||
|
@ -894,6 +894,54 @@ func zeroUpper32Bits(x *Value, depth int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// zeroUpper48Bits is similar to zeroUpper32Bits, but for upper 48 bits
|
||||
func zeroUpper48Bits(x *Value, depth int) bool {
|
||||
switch x.Op {
|
||||
case OpAMD64MOVWQZX, OpAMD64MOVWload, OpAMD64MOVWloadidx1, OpAMD64MOVWloadidx2:
|
||||
return true
|
||||
case OpArg:
|
||||
return x.Type.Width == 2
|
||||
case OpPhi, OpSelect0, OpSelect1:
|
||||
// Phis can use each-other as an arguments, instead of tracking visited values,
|
||||
// just limit recursion depth.
|
||||
if depth <= 0 {
|
||||
return false
|
||||
}
|
||||
for i := range x.Args {
|
||||
if !zeroUpper48Bits(x.Args[i], depth-1) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// zeroUpper56Bits is similar to zeroUpper32Bits, but for upper 56 bits
|
||||
func zeroUpper56Bits(x *Value, depth int) bool {
|
||||
switch x.Op {
|
||||
case OpAMD64MOVBQZX, OpAMD64MOVBload, OpAMD64MOVBloadidx1:
|
||||
return true
|
||||
case OpArg:
|
||||
return x.Type.Width == 1
|
||||
case OpPhi, OpSelect0, OpSelect1:
|
||||
// Phis can use each-other as an arguments, instead of tracking visited values,
|
||||
// just limit recursion depth.
|
||||
if depth <= 0 {
|
||||
return false
|
||||
}
|
||||
for i := range x.Args {
|
||||
if !zeroUpper56Bits(x.Args[i], depth-1) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// isInlinableMemmove reports whether the given arch performs a Move of the given size
|
||||
// faster than memmove. It will only return true if replacing the memmove with a Move is
|
||||
// safe, either because Move is small or because the arguments are disjoint.
|
||||
|
@ -10270,6 +10270,19 @@ func rewriteValueAMD64_OpAMD64MOVBQZX_0(v *Value) bool {
|
||||
v0.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBQZX x)
|
||||
// cond: zeroUpper56Bits(x,3)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if !(zeroUpper56Bits(x, 3)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBQZX x:(MOVBloadidx1 [off] {sym} ptr idx mem))
|
||||
// cond: x.Uses == 1 && clobber(x)
|
||||
// result: @x.Block (MOVBloadidx1 <v.Type> [off] {sym} ptr idx mem)
|
||||
@ -18893,6 +18906,19 @@ func rewriteValueAMD64_OpAMD64MOVWQZX_0(v *Value) bool {
|
||||
v0.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWQZX x)
|
||||
// cond: zeroUpper48Bits(x,3)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if !(zeroUpper48Bits(x, 3)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWQZX x:(MOVWloadidx1 [off] {sym} ptr idx mem))
|
||||
// cond: x.Uses == 1 && clobber(x)
|
||||
// result: @x.Block (MOVWloadidx1 <v.Type> [off] {sym} ptr idx mem)
|
||||
|
22
test/codegen/issue25378.go
Normal file
22
test/codegen/issue25378.go
Normal file
@ -0,0 +1,22 @@
|
||||
// asmcheck
|
||||
|
||||
// Copyright 2018 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 codegen
|
||||
|
||||
var wsp = [256]bool{
|
||||
' ': true,
|
||||
'\t': true,
|
||||
'\n': true,
|
||||
'\r': true,
|
||||
}
|
||||
|
||||
func zeroExtArgByte(ch byte) bool {
|
||||
return wsp[ch] // amd64:-"MOVBLZX\t..,.."
|
||||
}
|
||||
|
||||
func zeroExtArgUint16(ch uint16) bool {
|
||||
return wsp[ch] // amd64:-"MOVWLZX\t..,.."
|
||||
}
|
Loading…
Reference in New Issue
Block a user