mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.simd] cmd/compile: exclude simd vars from merge local
It looks like mergelocals pass's liveness analysis does not handle simd variables well. The added test forces two vectors to spill in a way that does not work with mergelocals: if the added check is removed, then `v` and `m` will be marked merged and spilled to the same location, failing the test. Change-Id: Ife4e4e939565d817fc24f7180cb791a5084dd191 Reviewed-on: https://go-review.googlesource.com/c/go/+/687375 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
ccb43dcec7
commit
1440ff7036
2 changed files with 34 additions and 0 deletions
|
|
@ -850,6 +850,13 @@ func (f *Func) NewLocal(pos src.XPos, typ *types.Type) *ir.Name {
|
|||
// items larger than what CanSSA would allow (approximateky, we disallow things
|
||||
// marked as open defer slots so as to avoid complicating liveness
|
||||
// analysis.
|
||||
//
|
||||
// TODO: make SIMD variables mergible.
|
||||
//
|
||||
// Right now this check excludes SIMD vars because sometimes two live SIMD
|
||||
// vectors will be put into the same partition by mergelocals, we need to figure
|
||||
// out why because these vectors are big and should be merged when possible.
|
||||
// Details in CL 687375.
|
||||
func IsMergeCandidate(n *ir.Name) bool {
|
||||
if base.Debug.MergeLocals == 0 ||
|
||||
base.Flag.N != 0 ||
|
||||
|
|
@ -857,6 +864,7 @@ func IsMergeCandidate(n *ir.Name) bool {
|
|||
n.Type().Size() <= int64(3*types.PtrSize) ||
|
||||
n.Addrtaken() ||
|
||||
n.NonMergeable() ||
|
||||
n.Type().IsSIMD() ||
|
||||
n.OpenDeferSlot() {
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -364,3 +364,29 @@ func TestSlicesFloat64(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: try to reduce this test to be smaller.
|
||||
func TestMergeLocals(t *testing.T) {
|
||||
testMergeLocalswrapper(t, simd.Int64x4.Add)
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func forceSpill() {}
|
||||
|
||||
func testMergeLocalswrapper(t *testing.T, op func(simd.Int64x4, simd.Int64x4) simd.Int64x4) {
|
||||
t.Helper()
|
||||
s0 := []int64{0, 1, 2, 3}
|
||||
s1 := []int64{-1, 0, -1, 0}
|
||||
want := []int64{-1, 1, 1, 3}
|
||||
v := simd.LoadInt64x4Slice(s0)
|
||||
m := simd.LoadInt64x4Slice(s1)
|
||||
forceSpill()
|
||||
got := make([]int64, 4)
|
||||
gotv := op(v, m)
|
||||
gotv.StoreSlice(got)
|
||||
for i := range len(want) {
|
||||
if !(got[i] == want[i]) {
|
||||
t.Errorf("Result at %d incorrect: want %v, got %v", i, want[i], got[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue