The "Procedure Call Procedure Call Standard for the ARM® Architecture" (https://static.docs.arm.com/ihi0042/f/IHI0042F_aapcs.pdf), specifies that composite types are passed according to their natural alignment:
5.5 Parameter Passing
...
B.5 If the argument is an alignment adjusted type its value is passed as a copy of the actual value. The
copy will have an alignment defined as follows.
- For a Fundamental Data Type, the alignment is the natural alignment of that type, after any
promotions
- For a Composite Type, the alignment of the copy will have 4-byte alignment if its natural alignment is <= 4 and 8-byte alignment if its natural alignment is >= 8
The "natural alignment" is defined as the maximum of the alignment of the top-level components:
4.3 Composite Types
...
- The natural alignment of a composite type is the maximum of each of the member alignments of the 'top-level' members of the composite type i.e. before any alignment adjustment of the entire composite is applied
clang, however, uses the actual alignment of the composite, instead of the natural alignment.
This patch fixes passing of composite types to use the natural alignment. With this patch clang conforms to AAPCS and is compatible with GCC.
This "default" isn't right; there are a lot of non-canonical types which need to be handled here (which getTypeAlign handles, but this doesn't).
Could you just write something like if (const auto *RTy = T->getAs<RecordType>()) [...] else return getTypeAlign(T);?