Currently, for the ppc64--gnu and aarch64 ABIs, we recognize:
typedef __attribute__((__ext_vector_type__(3))) float v3f32; typedef __attribute__((__ext_vector_type__(16))) char v16i8; struct HFA { v3f32 a; v16i8 b; };
as an HFA. Since the base type is the first type encountered, we pass the HFA as:
[2 x <3 x float>]
Which leads to incorrect IR (relying on padding values) when the second field is used.
This patch teaches isHomogeneousAggregate to explicitly uses the widened vector (after size rounding).
I don't know if this approach is either sufficient or ideal; alternatives I considered:
- pass as [2 x <3 x float>], but bitcast the struct pointer itself to [2 x <4 x float>]*; this still relies on accessing padding.
- return an llvm::Type (instead of QualType) in isHomogeneousAggregate: there are a couple callers that rely on size/alignment info which should come from the clang::Type.
- reject non-power-of-2 vectors as HFA base types: this doesn't make sense, as we treat them everywhere else as the next-power-of-2 type.
- fixup the base type in the various isHomogeneousAggregate callers: repetitive changes all over the place.