Size of stack allocations produced by LLVM's x86-64 backend
Asked Answered
W

0

0

I would like to understand how LLVM decides what size memory regions allocated with alloca should have. As can be seen in this example, when generating code for x86-64 it appears to always select a size that is an odd multiple of 8 bytes:

%0 = alloca [ 88 x i8] ; Allocates 88 bytes
%1 = alloca [ 96 x i8] ;
%2 = alloca [100 x i8] ; All allocate 104 bytes
%3 = alloca [104 x i8] ;
%4 = alloca [105 x i8] ; Allocates 120 bytes

So is this really the pattern that the code generator follows? And if so, why? Why not prefer even multiples of 8 or any multiple?

I tripped over this seemingly odd behaviour while trying to answer this question. It feels however as though I'm missing something regarding the size of the allocations.

Wingspan answered 19/5, 2023 at 19:24 Comment(4)
You're looking at each one in a separate function, so you're seeing LLVM aim for RSP%16 == 0 in preparation for another function call, as required by the ABI (glibc scanf Segmentation faults when called from a function that doesn't align RSP / Why does the x86-64 / AMD64 System V ABI mandate a 16 byte stack alignment?).Barracuda
The AMD64 SysV ABI also requires 16-byte alignment for arrays themselves if they're 16 bytes or larger, or VLAs. GCC applies this even to local array, but I guess LLVM feels that's overly intrusive into a function's private stack layout, since it's not externally observable except in cases like yours where you pass the address to another function. It's odd that clang isn't aligning its arrays (using lea rdi, [rsp+4] for some), since all the space is getting touched anyway. In a leaf function with -mno-red-zone you could observe placement by storing the address (like volatile char*)Barracuda
@PeterCordes I see, the 16 byte alignment makes sense, but where are the other 8 bytes going? I mean, none of the sizes are divisible by 16, so is RSP not 16 byte aligned when any of the functions are called?Wingspan
call pushes an 8-byte return address. As explained in those two Q&As I linked, RSP % 16 == 8 is guaranteed on function entry because RSP % 16 == 0 is required before a call. (Both AMD64 SysV and Windows x64 require that.)Barracuda

© 2022 - 2024 — McMap. All rights reserved.