]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.simd] cmd/compile: spill the correct SIMD register for morestack
authorCherry Mui <cherryyz@google.com>
Fri, 19 Sep 2025 03:46:41 +0000 (23:46 -0400)
committerCherry Mui <cherryyz@google.com>
Fri, 19 Sep 2025 15:06:23 +0000 (08:06 -0700)
If a SIMD value is passed in a register, make sure to spill/reload
with the right width.

Change-Id: I360e7b7a030bcd87c96e4c04ad42d87e7fd1bac6
Reviewed-on: https://go-review.googlesource.com/c/go/+/705415
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/compile/internal/amd64/ssa.go

index 5546ce8d5426a0ebf719ea3957c07f9ec6350b9e..0159d8ec07ad5fadcd68ed40510c13a0fa450b53 100644 (file)
@@ -1274,8 +1274,14 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                for _, ap := range v.Block.Func.RegArgs {
                        // Pass the spill/unspill information along to the assembler, offset by size of return PC pushed on stack.
                        addr := ssagen.SpillSlotAddr(ap, x86.REG_SP, v.Block.Func.Config.PtrSize)
+                       reg := ap.Reg
+                       t := ap.Type
+                       sz := t.Size()
+                       if t.IsSIMD() {
+                               reg = simdRegBySize(reg, sz)
+                       }
                        s.FuncInfo().AddSpill(
-                               obj.RegSpill{Reg: ap.Reg, Addr: addr, Unspill: loadByRegWidth(ap.Reg, ap.Type.Size()), Spill: storeByRegWidth(ap.Reg, ap.Type.Size())})
+                               obj.RegSpill{Reg: reg, Addr: addr, Unspill: loadByRegWidth(reg, sz), Spill: storeByRegWidth(reg, sz)})
                }
                v.Block.Func.RegArgs = nil
                ssagen.CheckArgReg(v)
@@ -2448,15 +2454,19 @@ func simdReg(v *ssa.Value) int16 {
        if !t.IsSIMD() {
                base.Fatalf("simdReg: not a simd type; v=%s, b=b%d, f=%s", v.LongString(), v.Block.ID, v.Block.Func.Name)
        }
-       switch t.Size() {
+       return simdRegBySize(v.Reg(), t.Size())
+}
+
+func simdRegBySize(reg int16, size int64) int16 {
+       switch size {
        case 16:
-               return v.Reg()
+               return reg
        case 32:
-               return v.Reg() + (x86.REG_Y0 - x86.REG_X0)
+               return reg + (x86.REG_Y0 - x86.REG_X0)
        case 64:
-               return v.Reg() + (x86.REG_Z0 - x86.REG_X0)
+               return reg + (x86.REG_Z0 - x86.REG_X0)
        }
-       panic("unreachable")
+       panic("simdRegBySize: bad size")
 }
 
 // XXX k mask