]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: use the right type for spill slot
authorCherry Mui <cherryyz@google.com>
Tue, 16 Sep 2025 01:27:19 +0000 (21:27 -0400)
committerCherry Mui <cherryyz@google.com>
Fri, 3 Oct 2025 19:30:36 +0000 (12:30 -0700)
Currently, when shuffling registers, if we need to spill a
register, we always create a spill slot of type int64. The type
doesn't actually matter, as long as it is wide enough to hold the
registers. This is no longer true with SIMD registers, which could
be wider than a int64. Create the slot with the proper type
instead.

Cherry-picked from the dev.simd branch. This CL is not
necessarily SIMD specific. Apply early to reduce risk. Test is
SIMD specific so not included for now.

Change-Id: I85c82e2532001bfdefe98c9446f2dd18583d49b4
Reviewed-on: https://go-review.googlesource.com/c/go/+/704055
TryBot-Bypass: Cherry Mui <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/708860
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/compile/internal/ssa/regalloc.go
src/cmd/compile/internal/ssa/value.go

index 56f9e550b2d43927138a6bb680805f42402bcd34..26c742d7fe78ffa2f89d644a6a0c512627a69992 100644 (file)
@@ -2690,7 +2690,6 @@ func (e *edgeState) erase(loc Location) {
 // findRegFor finds a register we can use to make a temp copy of type typ.
 func (e *edgeState) findRegFor(typ *types.Type) Location {
        // Which registers are possibilities.
-       types := &e.s.f.Config.Types
        m := e.s.compatRegs(typ)
 
        // Pick a register. In priority order:
@@ -2724,9 +2723,7 @@ func (e *edgeState) findRegFor(typ *types.Type) Location {
                                if !c.rematerializeable() {
                                        x := e.p.NewValue1(c.Pos, OpStoreReg, c.Type, c)
                                        // Allocate a temp location to spill a register to.
-                                       // The type of the slot is immaterial - it will not be live across
-                                       // any safepoint. Just use a type big enough to hold any register.
-                                       t := LocalSlot{N: e.s.f.NewLocal(c.Pos, types.Int64), Type: types.Int64}
+                                       t := LocalSlot{N: e.s.f.NewLocal(c.Pos, c.Type), Type: c.Type}
                                        // TODO: reuse these slots. They'll need to be erased first.
                                        e.set(t, vid, x, false, c.Pos)
                                        if e.s.f.pass.debug > regDebug {
index 55ab23ce9a0bcdd19aaa08534aa91cd492227ebf..51a70c7fd4fdcd35aa1ab12d997df0acfda21ad0 100644 (file)
@@ -600,7 +600,7 @@ func (v *Value) removeable() bool {
 func AutoVar(v *Value) (*ir.Name, int64) {
        if loc, ok := v.Block.Func.RegAlloc[v.ID].(LocalSlot); ok {
                if v.Type.Size() > loc.Type.Size() {
-                       v.Fatalf("spill/restore type %s doesn't fit in slot type %s", v.Type, loc.Type)
+                       v.Fatalf("v%d: spill/restore type %v doesn't fit in slot type %v", v.ID, v.Type, loc.Type)
                }
                return loc.N, loc.Off
        }