When we pass a Homogeneous Floating-Point Aggregate (HFA) argument
with increased alignment requirements, for example
struct S { __attribute__ ((__aligned__(16))) double v[4]; };
Clang uses [4 x double] for the parameter, which is passed on the
stack at alignment 8, whereas it should be at alignment 16, following
Rule C.4 in AAPCS (https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst#642parameter-passing-rules)
Currently we don't have a way to express in LLVM IR the alignment
requirements of the function arguments. The align attribute is
applicable to pointers only, and only for some special ways of passing
arguments (e..g byval). When implementing AAPCS32/AAPCS64, clang
resorts to dubious hacks of coercing to types, which naturally have
the needed alignment. We don't have enough types to cover all the
cases, though.
This patch introduces a new use of the stackalign attribute to
control stack slot alignment, when and if an argument is passed in
memory.
The attribute align is left as an optimizer hint - it still applies
to pointer types only and pertains to the content of the pointer,
whereas the alignment of the pointer itself is determined by the
stackalign attribute.
For byval arguments, the stackalign attribute assumes the role,
previously perfomed by align, falling back to align if
stackalign` is absent.
Patch by Momchil Velikov and Lucas Prates.
clang-format: please reformat the code