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.

chrysante
  • 2,328
  • 4
  • 24
  • 1
    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](https://stackoverflow.com/q/51070716) / [Why does the x86-64 / AMD64 System V ABI mandate a 16 byte stack alignment?](https://stackoverflow.com/q/49391001)). – Peter Cordes May 19 '23 at 19:43
  • 1
    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*`) – Peter Cordes May 19 '23 at 19:47
  • @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? – chrysante May 19 '23 at 19:53
  • 1
    `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.) – Peter Cordes May 19 '23 at 20:38

0 Answers0