1
0
mirror of https://github.com/golang/go synced 2024-11-11 22:10:22 -07:00

cmd/compile/internal-abi: fix ABI0-equivalence for zero-sized values

This fixes a bug in the internal ABI specification that made it not
equivalent to ABI0 even with zero architectural argument registers in
the case of a zero-sized argument with alignment > 1.

In ABI0, even zero-sized arguments cause alignment padding in the
stack frame.

Currently, in the internal ABI, zero-sized arguments get
register-assigned even if there are no registers because they don't
consume any registers. Hence, they don't create alignment padding in
the stack frame.

Fix this by stack-assigning zero-sized arguments.

For #40724.

Change-Id: I1f5a95a94fed8b5313a360e5e76875701ba5f562
Reviewed-on: https://go-review.googlesource.com/c/go/+/295791
Trust: Austin Clements <austin@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
Austin Clements 2021-02-23 20:48:22 -05:00
parent 3deb528199
commit 80ddc17ae1

View File

@ -153,6 +153,7 @@ Assigning a receiver, argument, or result V of underlying type T works
as follows:
1. Remember I and FP.
1. If T has zero size, add T to the stack sequence S and return.
1. Try to register-assign V.
1. If step 2 failed, reset I and FP to the values from step 1, add T
to the stack sequence S, and assign V to this field in S.
@ -295,6 +296,15 @@ An architecture may still define register meanings that arent
compatible with ABI0, but these differences should be easy to account
for in the compiler.
The assignment algorithm assigns zero-sized values to the stack
(assignment step 2) in order to support ABI0-equivalence.
While these values take no space themselves, they do result in
alignment padding on the stack in ABI0.
Without this step, the internal ABI would register-assign zero-sized
values even on architectures that provide no argument registers
because they don't consume any registers, and hence not add alignment
padding to the stack.
The algorithm reserves spill space for arguments in the callers frame
so that the compiler can generate a stack growth path that spills into
this reserved space.