cmd/compile: avoid extending when already sufficiently masked on loong64

Reduce the number of go toolchain instructions on loong64 as follows.

        file         before      after      Δ       %
        asm          562400      561348   -1052   -0.1871%
        cgo          488268      487932   -336    -0.0688%
        compile      2505750     2503710  -2040   -0.0814%
        cover        525874      525506   -368    -0.0700%
        link         714162      713562   -600    -0.0840%
        preprofile   240250      240054   -196    -0.0816%
        vet          794074      793742   -332    -0.0418%
        go           1598284     1597680  -604    -0.0378%
        gofmt        324126      323926   -200    -0.0617%
        total        7753188     7747460  -5728   -0.0739%

Change-Id: I3406113553b0fc4947d763ab66e57e69aa98c020
Reviewed-on: https://go-review.googlesource.com/c/go/+/683615
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Mark Freeman <mark@golang.org>
This commit is contained in:
Xiaolin Zhao 2025-06-23 17:45:26 +08:00 committed by abner chenc
parent 880ca333d7
commit b1e933d955
2 changed files with 98 additions and 0 deletions

View file

@ -843,6 +843,14 @@
(MOVBUreg (ANDconst [c] x)) => (ANDconst [c&0xff] x)
// Avoid extending when already sufficiently masked.
(MOVBreg x:(ANDconst [c] y)) && c >= 0 && int64(int8(c)) == c => x
(MOVHreg x:(ANDconst [c] y)) && c >= 0 && int64(int16(c)) == c => x
(MOVWreg x:(ANDconst [c] y)) && c >= 0 && int64(int32(c)) == c => x
(MOVBUreg x:(ANDconst [c] y)) && c >= 0 && int64(uint8(c)) == c => x
(MOVHUreg x:(ANDconst [c] y)) && c >= 0 && int64(uint16(c)) == c => x
(MOVWUreg x:(ANDconst [c] y)) && c >= 0 && int64(uint32(c)) == c => x
// Prefetch instructions (hint specified using aux field)
// For PRELD{,X} A value of hint indicates:
// hint=0 is defined as load prefetch to L1-cache

View file

@ -2378,6 +2378,21 @@ func rewriteValueLOONG64_OpLOONG64MOVBUreg(v *Value) bool {
v.AddArg(x)
return true
}
// match: (MOVBUreg x:(ANDconst [c] y))
// cond: c >= 0 && int64(uint8(c)) == c
// result: x
for {
x := v_0
if x.Op != OpLOONG64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
if !(c >= 0 && int64(uint8(c)) == c) {
break
}
v.copyOf(x)
return true
}
return false
}
func rewriteValueLOONG64_OpLOONG64MOVBload(v *Value) bool {
@ -2526,6 +2541,21 @@ func rewriteValueLOONG64_OpLOONG64MOVBreg(v *Value) bool {
v.AuxInt = int64ToAuxInt(int64(int8(c)))
return true
}
// match: (MOVBreg x:(ANDconst [c] y))
// cond: c >= 0 && int64(int8(c)) == c
// result: x
for {
x := v_0
if x.Op != OpLOONG64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
if !(c >= 0 && int64(int8(c)) == c) {
break
}
v.copyOf(x)
return true
}
return false
}
func rewriteValueLOONG64_OpLOONG64MOVBstore(v *Value) bool {
@ -3614,6 +3644,21 @@ func rewriteValueLOONG64_OpLOONG64MOVHUreg(v *Value) bool {
v.AuxInt = int64ToAuxInt(int64(uint16(c)))
return true
}
// match: (MOVHUreg x:(ANDconst [c] y))
// cond: c >= 0 && int64(uint16(c)) == c
// result: x
for {
x := v_0
if x.Op != OpLOONG64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
if !(c >= 0 && int64(uint16(c)) == c) {
break
}
v.copyOf(x)
return true
}
return false
}
func rewriteValueLOONG64_OpLOONG64MOVHload(v *Value) bool {
@ -3806,6 +3851,21 @@ func rewriteValueLOONG64_OpLOONG64MOVHreg(v *Value) bool {
v.AuxInt = int64ToAuxInt(int64(int16(c)))
return true
}
// match: (MOVHreg x:(ANDconst [c] y))
// cond: c >= 0 && int64(int16(c)) == c
// result: x
for {
x := v_0
if x.Op != OpLOONG64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
if !(c >= 0 && int64(int16(c)) == c) {
break
}
v.copyOf(x)
return true
}
return false
}
func rewriteValueLOONG64_OpLOONG64MOVHstore(v *Value) bool {
@ -4821,6 +4881,21 @@ func rewriteValueLOONG64_OpLOONG64MOVWUreg(v *Value) bool {
v.AuxInt = int64ToAuxInt(int64(uint32(c)))
return true
}
// match: (MOVWUreg x:(ANDconst [c] y))
// cond: c >= 0 && int64(uint32(c)) == c
// result: x
for {
x := v_0
if x.Op != OpLOONG64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
if !(c >= 0 && int64(uint32(c)) == c) {
break
}
v.copyOf(x)
return true
}
return false
}
func rewriteValueLOONG64_OpLOONG64MOVWload(v *Value) bool {
@ -5046,6 +5121,21 @@ func rewriteValueLOONG64_OpLOONG64MOVWreg(v *Value) bool {
v.AuxInt = int64ToAuxInt(int64(int32(c)))
return true
}
// match: (MOVWreg x:(ANDconst [c] y))
// cond: c >= 0 && int64(int32(c)) == c
// result: x
for {
x := v_0
if x.Op != OpLOONG64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
if !(c >= 0 && int64(int32(c)) == c) {
break
}
v.copyOf(x)
return true
}
return false
}
func rewriteValueLOONG64_OpLOONG64MOVWstore(v *Value) bool {