// 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 ||
n.Type().Size() <= int64(3*types.PtrSize) ||
n.Addrtaken() ||
n.NonMergeable() ||
+ n.Type().IsSIMD() ||
n.OpenDeferSlot() {
return false
}
}
}
}
+
+// 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])
+ }
+ }
+}