cmd/compile: recognize OpVarDef and OpZero in cse isMemDef

recognize OpVarDef (width 0, always skippable) and OpZero (similar to
OpStore, it should be disjoint), so these ops do not prevent loads cse.

This change slightly improves code size:

Executable           Base .text linux_arm64     Change
----------------------------------------------------
asm                     2133284     2132900     -0.02%
cgo                     1742996     1742868     -0.01%
compile                10567620    10566852     -0.01%
cover                   1906740     1906100     -0.03%
fix                     3131284     3131012     -0.01%
link                    2667604     2667076     -0.02%
preprofile               877908      877876     -0.00%
vet                     3010372     3010084     -0.01%

Change-Id: I428f73008a817d0e302d438c020504c560ae1653
Reviewed-on: https://go-review.googlesource.com/c/go/+/769000
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Auto-Submit: Keith Randall <khr@golang.org>
This commit is contained in:
Alexander Musman 2026-04-20 17:05:40 +03:00 committed by Gopher Robot
parent e4e2474e12
commit 13cab13f78
2 changed files with 18 additions and 0 deletions

View file

@ -472,10 +472,15 @@ func isMemUser(v *Value) (int, int, int64, bool) {
// Query if the given "memory"-defining instruction's memory destination can be analyzed for aliasing with a memory "user" instructions.
// Return index of pointer argument, index of "memory" argument, the access width and true on such instructions, otherwise return (-1, -1, 0, false).
// If the access width is 0, the pointer index may be -1 (no pointer operand is needed).
func isMemDef(v *Value) (int, int, int64, bool) {
switch v.Op {
case OpStore:
return 0, 2, auxToType(v.Aux).Size(), true
case OpVarDef:
return -1, 0, 0, true
case OpZero:
return 0, 1, v.AuxInt, true
default:
return -1, -1, 0, false
}
@ -525,6 +530,10 @@ func skipDisjointMemDefs(user *Value, idxUserPtr, idxUserMem int, useWidth int64
// Skipping a memory def with a lot of uses may potentially increase register pressure.
break
}
if width == 0 {
mem = mem.Args[idxMem]
continue
}
defPtr := mem.Args[idxPtr]
if disjoint(defPtr, width, usePtr, useWidth) {
mem = mem.Args[idxMem]

View file

@ -15,3 +15,12 @@ func loadsAroundMemEqual(p *int, s1, s2 string) (int, bool) {
// arm64:"MOVD ZR, R0"
return x - y, eq
}
func loadsAroundVarDefAndZero(p *int) (int, *int) {
x := *p
var s [2]*int
s[0] = p
y := *p
// arm64:"MOVD ZR, R0"
return x - y, s[0]
}