]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.simd] cmd/compile: exclude simd vars from merge local
authorJunyang Shao <shaojunyang@google.com>
Thu, 10 Jul 2025 22:04:21 +0000 (22:04 +0000)
committerJunyang Shao <shaojunyang@google.com>
Fri, 11 Jul 2025 19:07:31 +0000 (12:07 -0700)
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>
src/cmd/compile/internal/ssa/func.go
src/simd/simd_test.go

index 5736f0b8126484bdc0150cef7373b55ac081eb71..01ce89cf47e3155892f81e3571451e3a12b76918 100644 (file)
@@ -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
        }
index ebe241c46744664d370722509cde37ea0711a09c..36923319ff312c9f6a0144c21c4a4fae9aa3ad42 100644 (file)
@@ -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])
+               }
+       }
+}