1
0
mirror of https://github.com/golang/go synced 2024-11-23 07:00:05 -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:
Ilya Tocar 2018-05-31 16:38:18 -05:00
parent c292b32f33
commit a3593685cf
4 changed files with 98 additions and 0 deletions

View File

@ -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:(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 (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) (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) (MOVWQZX x:(MOVWloadidx1 [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx1 <v.Type> [off] {sym} ptr idx mem)

View File

@ -894,6 +894,54 @@ func zeroUpper32Bits(x *Value, depth int) bool {
return false 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 // 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 // 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. // safe, either because Move is small or because the arguments are disjoint.

View File

@ -10270,6 +10270,19 @@ func rewriteValueAMD64_OpAMD64MOVBQZX_0(v *Value) bool {
v0.AddArg(mem) v0.AddArg(mem)
return true 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)) // match: (MOVBQZX x:(MOVBloadidx1 [off] {sym} ptr idx mem))
// cond: x.Uses == 1 && clobber(x) // cond: x.Uses == 1 && clobber(x)
// result: @x.Block (MOVBloadidx1 <v.Type> [off] {sym} ptr idx mem) // 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) v0.AddArg(mem)
return true 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)) // match: (MOVWQZX x:(MOVWloadidx1 [off] {sym} ptr idx mem))
// cond: x.Uses == 1 && clobber(x) // cond: x.Uses == 1 && clobber(x)
// result: @x.Block (MOVWloadidx1 <v.Type> [off] {sym} ptr idx mem) // result: @x.Block (MOVWloadidx1 <v.Type> [off] {sym} ptr idx mem)

View 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..,.."
}