Hi all,
Refer to the Go internal ABI specification https://go.googlesource.com/go/+/refs/heads/dev.regabi/src/cmd/compile/internal-abi.md, the stack frame is shown in the diagram below.

The allocation of register parameter spill space looks strange. In the below example, before bar() calls add(), bar() needs to spill register-assigned arguments ‘a1’ and ‘a3’ to the spill space on frame stack. According to my understanding, the spill space for ‘a1’ and ‘a2’ should be allocated on bar()’s frame stack. But the current implementation spills the first register-assigned argument ‘a1’ to bar()’s frame stack and spills the second register-assigned argument ‘a3’ to main()’s frame stack. Please see the below assembly codes.
// source code.
func main() {
a := [1]int{40}
b := [2]int{10, 20}
c := 30
d := bar(a, b, c)
fmt.Println(d)
}
//go:noinline
func bar(a1 [1]int, a2 [2]int, a3 int) int {
var t int
t += a2[0]
t += a2[1]
r := add(t, a3) // spill register-assigned arguments to stack.
r += a1[0] + a3
return r
}
//go:noinline
func add(a, b int) int {
return a+b
}
// assembly codes.
![]()
![]()
![]()
![]()
![]()
![]()

The size of bar()’s stack frame is 32 bytes, I think 16 bytes of it should be allocated for spill space. So my question is why the argument ‘a3’ is spilled to main()’s frame stack not bar()’s frame stack? Thank you.
Best regards,
Fannie Zhang
Hi all,
Refer to the Go internal ABI specification https://go.googlesource.com/go/+/refs/heads/dev.regabi/src/cmd/compile/internal-abi.md, the stack frame is shown in the diagram below.
Hello Fannie,In the current implementation, in theory, if an in-register argument needs to be spilled, it spills to the caller's frame, next to the on-stack arguments. So in your example both a1 and a3 _should_ spill to bar's argument area, which is in the caller of bar, i.e. main's frame. However, there is a known bug that it sometimes spills to the wrong place, to its own frame (in your case, bar's frame). It does not affect the correctness of code execution, but it is still good to be fixed (not in Go 1.17).
By the way, the dev.regabi branch is not active anymore. Please refer to the main branch or the dev.typeparams branch. Thanks.
--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/cb8599b5-3d59-4c22-b857-249e999c0653n%40googlegroups.com.