[PATCH] Correctly align arguments after a byval struct is passed on the stack

Oliver Stannard oliver.stannard at arm.com
Tue Mar 4 03:36:00 PST 2014

Hi rengolin,

This patch fixes a bug that would cause an 8-byte-aligned function argument
to be consistently misaligned in some situations involving byval arguments.
The following function signature is one of these cases:

%struct12bytes = type { i32, i32, i32 }
define void @foo(i32 %a, %struct12bytes* byval %b, i64 %c) {

When arguments are initially been allocated, %b has 12 bytes reserved on the
stack, but this is later adjusted to use registers r1..r3 instead of the
stack. However, the 12 bytes are still used when calculating the alignment
of %c, causing %c to be allocated 4 bytes above the top of %b, at stack
offset 0x10. The stack pointer is moved down 12 bytes at the beginning of
the function  to make space for the part of %b which is in registers (all of
it in this example), plus another 4 bytes to maintain 8-byte SP alignment.
However, the 4 bytes of alignment gap between %b and %c are still present,
resulting in %c being loaded from SP+0x14, which is not 8-byte aligned.

The solution to this is to not allocate stack space for the part of a byval
which will be passed in registers. This requires some extra work to
calculate the location of byval arguments on the stack, especially in the
case of multiple small byvals in registers, as previously the stack
locations were used to record the location of a byval after storing to the

This bug can be triggered from C, using a similar test case, but argument b
must be larger than 64 bytes to cause clang to emit a byval argument.

I have put this patch through a night of random PCS testing with no failures.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2933.1.patch
Type: text/x-patch
Size: 22307 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140304/1d390a3d/attachment.bin>

More information about the llvm-commits mailing list