]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: enforce that locals are always accessed with SP base register
authorKeith Randall <khr@golang.org>
Fri, 1 Aug 2025 14:38:55 +0000 (07:38 -0700)
committerKeith Randall <khr@golang.org>
Fri, 1 Aug 2025 15:57:29 +0000 (08:57 -0700)
After CL 678937, we could have a situation where the value of the
stack pointer is in both SP and another register. We need to make sure
that regalloc picks SP when issuing a reference to local variables;
the assembler expects that.

Fixes #74836

Change-Id: I2ac73ece6eb44b4a78c1369f8a69e51ab9748754
Reviewed-on: https://go-review.googlesource.com/c/go/+/692395
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Mark Freeman <mark@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/compile/internal/ssa/regalloc.go
test/fixedbugs/issue74836.go [new file with mode: 0644]

index de49bb40c5271b8a79ce0c87708580117a139f15..fb9642cfedfbfd651548690862defce6d1d81987 100644 (file)
@@ -1583,6 +1583,12 @@ func (s *regAllocState) regalloc(f *Func) {
                                                mask &^= desired.avoid
                                        }
                                }
+                               if mask&s.values[v.Args[i.idx].ID].regs&(1<<s.SPReg) != 0 {
+                                       // Prefer SP register. This ensures that local variables
+                                       // use SP as their base register (instead of a copy of the
+                                       // stack pointer living in another register). See issue 74836.
+                                       mask = 1 << s.SPReg
+                               }
                                args[i.idx] = s.allocValToReg(v.Args[i.idx], mask, true, v.Pos)
                        }
 
diff --git a/test/fixedbugs/issue74836.go b/test/fixedbugs/issue74836.go
new file mode 100644 (file)
index 0000000..3e61c71
--- /dev/null
@@ -0,0 +1,17 @@
+// compile
+
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type T struct {
+       a [20]int
+}
+
+func f(x [4]int) {
+       g(T{}, x)
+}
+
+func g(t T, x [4]int)