Revert "cmd/compile: improve stp merging for non-sequent cases"

This reverts commit 4c63d798cb.

Reason for revert: Causes miscompilations. See issue 75365.

Change-Id: Icd1fcfeb23d2ec524b16eb556030f43875e1c90d
Reviewed-on: https://go-review.googlesource.com/c/go/+/702455
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Mark Freeman <markfreeman@google.com>
This commit is contained in:
Keith Randall
2025-09-10 10:39:17 -07:00
committed by Gopher Robot
parent f327a05419
commit 80a2aae922
2 changed files with 6 additions and 133 deletions

View File

@@ -212,12 +212,6 @@ func pairStores(f *Func) {
last := f.Cache.allocBoolSlice(f.NumValues())
defer f.Cache.freeBoolSlice(last)
type stChainElem struct {
v *Value
i int // Index in chain (0 == last store)
}
var order []stChainElem
// prevStore returns the previous store in the
// same block, or nil if there are none.
prevStore := func(v *Value) *Value {
@@ -231,27 +225,6 @@ func pairStores(f *Func) {
return m
}
// storeWidth returns the width of store,
// or 0 if it is not a store
storeWidth := func(op Op) int64 {
var width int64
switch op {
case OpARM64MOVDstore, OpARM64FMOVDstore:
width = 8
case OpARM64MOVWstore, OpARM64FMOVSstore:
width = 4
case OpARM64MOVHstore:
width = 2
case OpARM64MOVBstore:
width = 1
default:
width = 0
}
return width
}
const limit = 10
for _, b := range f.Blocks {
// Find last store in block, so we can
// walk the stores last to first.
@@ -277,84 +250,9 @@ func pairStores(f *Func) {
}
}
order = order[:0]
for i, v := 0, lastMem; v != nil; v = prevStore(v) {
order = append(order, stChainElem{v, i})
i++
}
reordering:
for i, v_elem := range order {
v := v_elem.v
if v.Uses != 1 {
// We can't reorder stores if the earlier
// store has any use besides the next one
// in the store chain.
// (Unless we could check the aliasing of
// all those other uses.)
continue
}
widthV := storeWidth(v.Op)
if widthV == 0 {
// Can't reorder with any other memory operations.
// (atomics, calls, ...)
continue
}
chain := order[i+1:]
count := limit
// Var 'count' keeps us in O(n) territory
for j, w_elem := range chain {
if count--; count == 0 {
// Only look back so far.
// This keeps us in O(n) territory, and it
// also prevents us from keeping values
// in registers for too long (and thus
// needing to spill them).
continue reordering
}
w := w_elem.v
if w.Uses != 1 {
// We can't reorder stores if the earlier
// store has any use besides the next one
// in the store chain.
// (Unless we could check the aliasing of
// all those other uses.)
continue reordering
}
widthW := storeWidth(w.Op)
if widthW == 0 {
// Can't reorder with any other memory operations.
// (atomics, calls, ...)
continue reordering
}
// We only allow reordering with respect to other
// writes to the same pointer and aux, so we can
// compute the exact the aliasing relationship.
if w.Args[0] != v.Args[0] ||
w.Aux != v.Aux {
// Can't reorder with operation with incomparable destination memory pointer.
continue reordering
}
if overlap(w.AuxInt, widthW, v.AuxInt, widthV) {
// Aliases with the same slot with v's location.
continue reordering
}
// Reordering stores in increasing order of memory access
if v.AuxInt < w.AuxInt {
order[i], order[i+j+1] = order[i+j+1], order[i]
v = w
widthV = widthW
}
}
}
// Check all stores, from last to first.
memCheck:
for i, v_elem := range order {
v := v_elem.v
for v := lastMem; v != nil; v = prevStore(v) {
info := pairableStores[v.Op]
if info.width == 0 {
continue // Not pairable.
@@ -371,10 +269,8 @@ func pairStores(f *Func) {
// Look for earlier store we can combine with.
lowerOk := true
higherOk := true
count := limit // max lookback distance
chain := order[i+1:]
for _, w_elem := range chain {
w := w_elem.v
count := 10 // max lookback distance
for w := prevStore(v); w != nil; w = prevStore(w) {
if w.Uses != 1 {
// We can't combine stores if the earlier
// store has any use besides the next one
@@ -397,17 +293,11 @@ func pairStores(f *Func) {
args[1], args[2] = args[2], args[1]
off -= info.width
}
v.reset(info.pair)
v.AddArgs(args...)
v.Aux = aux
v.AuxInt = off
// Take position of earlier of the two stores
if v_elem.i < w_elem.i {
v.Pos = w.Pos
} else {
w.Pos = v.Pos
}
v.Pos = w.Pos // take position of earlier of the two stores (TODO: not really working?)
// Make w just a memory copy.
wmem := w.MemoryArg()

View File

@@ -1053,34 +1053,17 @@ func dwstoreF32(p *struct{ a, b float32 }, x, y float32) {
}
func dwstoreBig(p *struct{ a, b, c, d, e, f int64 }, a, b, c, d, e, f int64) {
// arm64:`STP\s\(R[0-9]+, R[0-9]+\), 16\(R[0-9]+\)`
// This is not perfect. We merge b+a, then d+e, then c and f have no pair.
p.c = c
// arm64:`STP\s\(R[0-9]+, R[0-9]+\), 32\(R[0-9]+\)`
p.f = f
// arm64:`STP\s\(R[0-9]+, R[0-9]+\), \(R[0-9]+\)`
p.a = a
// arm64:`STP\s\(R[0-9]+, R[0-9]+\), 24\(R[0-9]+\)`
p.e = e
p.d = d
p.b = b
}
func dwstoreUnorderedArray(p *struct{ a, b, c, d int }, a, b, c, d int) {
// arm64:`STP\s\(R[0-9]+, R[0-9]+\), 16\(R[0-9]+\)`
p.c = c
p.d = d
// arm64:`STP\s\(R[0-9]+, R[0-9]+\), \(R[0-9]+\)`
p.a = a
p.b = b
}
func dwstoreBigNil(p *struct{ i, j struct{ a, b, c int } }) {
// arm64:`STP\s\(ZR, ZR\), 32\(R[0-9]+\)`
// arm64:`STP\s\(ZR, ZR\), 16\(R[0-9]+\)`
p.j = struct{ a, b, c int }{}
// arm64:`STP\s\(ZR, ZR\), \(R[0-9]+\)`
p.i = struct{ a, b, c int }{}
}
func dwstoreRet() [2]int {
// arm64:"STP\t"
return [2]int{5, 6}