[ARM, AArch64]: Use unadjusted alignment when passing composites as arguments
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", i.e. the
alignment before alignment adjustment on the entire composite is applied.
The same applies for AArch64 ABI.
Clang, however, used the adjusted alignment.
GCC already implements the ABI correctly. With this patch Clang becomes
compatible with GCC and passes such arguments in accordance with AAPCS.
Differential Revision: https://reviews.llvm.org/D46013
llvm-svn: 338279
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 25dc444..ab428e3 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -2056,6 +2056,27 @@
return TypeInfo(Width, Align, AlignIsRequired);
}
+unsigned ASTContext::getTypeUnadjustedAlign(const Type *T) const {
+ UnadjustedAlignMap::iterator I = MemoizedUnadjustedAlign.find(T);
+ if (I != MemoizedUnadjustedAlign.end())
+ return I->second;
+
+ unsigned UnadjustedAlign;
+ if (const auto *RT = T->getAs<RecordType>()) {
+ const RecordDecl *RD = RT->getDecl();
+ const ASTRecordLayout &Layout = getASTRecordLayout(RD);
+ UnadjustedAlign = toBits(Layout.getUnadjustedAlignment());
+ } else if (const auto *ObjCI = T->getAs<ObjCInterfaceType>()) {
+ const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
+ UnadjustedAlign = toBits(Layout.getUnadjustedAlignment());
+ } else {
+ UnadjustedAlign = getTypeAlign(T);
+ }
+
+ MemoizedUnadjustedAlign[T] = UnadjustedAlign;
+ return UnadjustedAlign;
+}
+
unsigned ASTContext::getOpenMPDefaultSimdAlign(QualType T) const {
unsigned SimdAlign = getTargetInfo().getSimdDefaultAlign();
// Target ppc64 with QPX: simd default alignment for pointer to double is 32.
@@ -2095,6 +2116,16 @@
return toCharUnitsFromBits(getTypeAlign(T));
}
+/// getTypeUnadjustedAlignInChars - Return the ABI-specified alignment of a
+/// type, in characters, before alignment adustments. This method does
+/// not work on incomplete types.
+CharUnits ASTContext::getTypeUnadjustedAlignInChars(QualType T) const {
+ return toCharUnitsFromBits(getTypeUnadjustedAlign(T));
+}
+CharUnits ASTContext::getTypeUnadjustedAlignInChars(const Type *T) const {
+ return toCharUnitsFromBits(getTypeUnadjustedAlign(T));
+}
+
/// getPreferredTypeAlign - Return the "preferred" alignment of the specified
/// type for the current target in bits. This can be different than the ABI
/// alignment in cases where it is beneficial for performance to overalign