diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -253,9 +253,11 @@ mutable llvm::DenseMap ObjCLayouts; - /// A cache from types to size and alignment information. using TypeInfoMap = llvm::DenseMap; + /// A cache from types to size and ABI-specified alignment information. mutable TypeInfoMap MemoizedTypeInfo; + /// /// A cache from types to size and preferred alignment information. + mutable TypeInfoMap MemoizedPreferredTypeInfo; /// A cache from types to unadjusted alignment information. Only ARM and /// AArch64 targets need this information, keeping it separate prevents @@ -2040,7 +2042,7 @@ private: CanQualType getFromTargetType(unsigned Type) const; - TypeInfo getTypeInfoImpl(const Type *T) const; + TypeInfo getTypeInfoImpl(const Type *T, bool NeedsPreferredAlignment) const; //===--------------------------------------------------------------------===// // Type Predicates. @@ -2078,15 +2080,24 @@ const llvm::fltSemantics &getFloatTypeSemantics(QualType T) const; /// Get the size and alignment of the specified complete type in bits. - TypeInfo getTypeInfo(const Type *T) const; - TypeInfo getTypeInfo(QualType T) const { return getTypeInfo(T.getTypePtr()); } + /// Set "NeedsPreferredAlignment" as true to return the preferred alignment + /// when allocating memory for a variable on the stack or in global/thread + /// local memory. Otherwise, return the ABI-specified alignment. + TypeInfo getTypeInfo(const Type *T, bool NeedsPreferredAlignment) const; + TypeInfo getTypeInfo(QualType T, bool NeedsPreferredAlignment) const { + return getTypeInfo(T.getTypePtr(), NeedsPreferredAlignment); + } /// Get default simd alignment of the specified complete type in bits. unsigned getOpenMPDefaultSimdAlign(QualType T) const; /// Return the size of the specified (complete) type \p T, in bits. - uint64_t getTypeSize(QualType T) const { return getTypeInfo(T).Width; } - uint64_t getTypeSize(const Type *T) const { return getTypeInfo(T).Width; } + uint64_t getTypeSize(QualType T) const { + return getTypeInfo(T, false /* NeedsPreferredAlignment */).Width; + } + uint64_t getTypeSize(const Type *T) const { + return getTypeInfo(T, false /* NeedsPreferredAlignment */).Width; + } /// Return the size of the character type, in bits. uint64_t getCharWidth() const { @@ -2118,10 +2129,17 @@ /// 'arm_sve_vector_bits'. Should only be called if T->isVLST(). unsigned getBitwidthForAttributedSveType(const Type *T) const; - /// Return the ABI-specified alignment of a (complete) type \p T, in - /// bits. - unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).Align; } - unsigned getTypeAlign(const Type *T) const { return getTypeInfo(T).Align; } + /// Set "NeedsPreferredAlignment" as true to return the preferred alignment + /// of a complete type \p T only when allocating memory for a variable on the + /// the stack or in global/thread local memory. + /// Otherwise, return the ABI-specified alignment of a (complete) type \p T, + /// in bits. + unsigned getTypeAlign(QualType T, bool NeedsPreferredAlignment) const { + return getTypeInfo(T, NeedsPreferredAlignment).Align; + } + unsigned getTypeAlign(const Type *T, bool NeedsPreferredAlignment) const { + return getTypeInfo(T, NeedsPreferredAlignment).Align; + } /// Return the ABI-specified natural alignment of a (complete) type \p T, /// before alignment adjustments, in bits. @@ -2133,15 +2151,22 @@ } unsigned getTypeUnadjustedAlign(const Type *T) const; - /// Return the ABI-specified alignment of a type, in bits, or 0 if - /// the type is incomplete and we cannot determine the alignment (for - /// example, from alignment attributes). - unsigned getTypeAlignIfKnown(QualType T) const; - - /// Return the ABI-specified alignment of a (complete) type \p T, in - /// characters. - CharUnits getTypeAlignInChars(QualType T) const; - CharUnits getTypeAlignInChars(const Type *T) const; + /// Set "NeedsPreferredAlignment" as true to return the preferred alignment + /// of a complete type \p T only when allocating memory for a variable on the + /// the stack or in global/thread local memory. Otherwise, return the + /// ABI-specified alignment of a (complete) type \p T, in bits. Return 0 if + /// the type is incomplete and we cannot determine the alignment (for example, + /// from alignment attributes). + unsigned getTypeAlignIfKnown(QualType T, bool NeedsPreferredAlignment) const; + + /// Set "NeedsPreferredAlignment" as true to return the preferred alignment + /// of a complete type \p T only when allocating memory for a variable on the + /// the stack or in global/thread local memory. + /// Otherwise, return the ABI-specified alignment of a (complete) type \p T, + /// in characters. + CharUnits getTypeAlignInChars(QualType T, bool NeedsPreferredAlignment) const; + CharUnits getTypeAlignInChars(const Type *T, + bool NeedsPreferredAlignment) const; /// getTypeUnadjustedAlignInChars - Return the ABI-specified alignment of a type, /// in characters, before alignment adjustments. This method does not work on @@ -2153,8 +2178,14 @@ // type is a record, its data size is returned. std::pair getTypeInfoDataSizeInChars(QualType T) const; - std::pair getTypeInfoInChars(const Type *T) const; - std::pair getTypeInfoInChars(QualType T) const; + /// Get the size and alignment of the specified complete type in characters. + /// Set "NeedsPreferredAlignment" as true to return the preferred alignment + /// when allocating memory for a variable on the stack or in global/thread + /// local memory. Otherwise, return the ABI-specified alignment. + std::pair + getTypeInfoInChars(const Type *T, bool NeedsPreferredAlignment) const; + std::pair + getTypeInfoInChars(QualType T, bool NeedsPreferredAlignment) const; /// Determine if the alignment the type has was required using an /// alignment attribute. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1712,7 +1712,9 @@ } QualType BaseT = getBaseElementType(T); if (T->isFunctionType()) - Align = getTypeInfoImpl(T.getTypePtr()).Align; + Align = + getTypeInfoImpl(T.getTypePtr(), false /* NeedsPreferredAlignment */) + .Align; else if (!BaseT->isIncompleteType()) { // Adjust alignments of declarations with array type by the // large-array alignment on the target. @@ -1779,7 +1781,8 @@ // using a trivial copy/move assignment operator. std::pair ASTContext::getTypeInfoDataSizeInChars(QualType T) const { - std::pair sizeAndAlign = getTypeInfoInChars(T); + std::pair sizeAndAlign = + getTypeInfoInChars(T, false /* NeedsPreferredAlignment */); // In C++, objects can sometimes be allocated into the tail padding // of a base-class subobject. We decide whether that's possible @@ -1796,11 +1799,11 @@ /// getConstantArrayInfoInChars - Performing the computation in CharUnits /// instead of in bits prevents overflowing the uint64_t for some large arrays. -std::pair -static getConstantArrayInfoInChars(const ASTContext &Context, - const ConstantArrayType *CAT) { - std::pair EltInfo = - Context.getTypeInfoInChars(CAT->getElementType()); +std::pair static getConstantArrayInfoInChars( + const ASTContext &Context, const ConstantArrayType *CAT, + bool NeedsPreferredAlignment) { + std::pair EltInfo = Context.getTypeInfoInChars( + CAT->getElementType(), NeedsPreferredAlignment); uint64_t Size = CAT->getSize().getZExtValue(); assert((Size == 0 || static_cast(EltInfo.first.getQuantity()) <= (uint64_t)(-1)/Size) && @@ -1815,28 +1818,30 @@ } std::pair -ASTContext::getTypeInfoInChars(const Type *T) const { +ASTContext::getTypeInfoInChars(const Type *T, + bool NeedsPreferredAlignment) const { if (const auto *CAT = dyn_cast(T)) - return getConstantArrayInfoInChars(*this, CAT); - TypeInfo Info = getTypeInfo(T); + return getConstantArrayInfoInChars(*this, CAT, NeedsPreferredAlignment); + TypeInfo Info = getTypeInfo(T, NeedsPreferredAlignment); return std::make_pair(toCharUnitsFromBits(Info.Width), toCharUnitsFromBits(Info.Align)); } std::pair -ASTContext::getTypeInfoInChars(QualType T) const { - return getTypeInfoInChars(T.getTypePtr()); +ASTContext::getTypeInfoInChars(QualType T, bool NeedsPreferredAlignment) const { + return getTypeInfoInChars(T.getTypePtr(), NeedsPreferredAlignment); } bool ASTContext::isAlignmentRequired(const Type *T) const { - return getTypeInfo(T).AlignIsRequired; + return getTypeInfo(T, false /* NeedsPreferredAlignment */).AlignIsRequired; } bool ASTContext::isAlignmentRequired(QualType T) const { return isAlignmentRequired(T.getTypePtr()); } -unsigned ASTContext::getTypeAlignIfKnown(QualType T) const { +unsigned ASTContext::getTypeAlignIfKnown(QualType T, + bool NeedsPreferredAlignment) const { // An alignment on a typedef overrides anything else. if (const auto *TT = T->getAs()) if (unsigned Align = TT->getDecl()->getMaxAlignment()) @@ -1845,7 +1850,7 @@ // If we have an (array of) complete type, we're done. T = getBaseElementType(T); if (!T->isIncompleteType()) - return getTypeAlign(T); + return getTypeAlign(T, NeedsPreferredAlignment); // If we had an array type, its element type might be a typedef // type with an alignment attribute. @@ -1860,15 +1865,21 @@ return 0; } -TypeInfo ASTContext::getTypeInfo(const Type *T) const { - TypeInfoMap::iterator I = MemoizedTypeInfo.find(T); - if (I != MemoizedTypeInfo.end()) - return I->second; +TypeInfo ASTContext::getTypeInfo(const Type *T, + bool NeedsPreferredAlignment) const { + auto getTypeInfo = [&](auto &TIMap) { + TypeInfoMap::iterator I = TIMap.find(T); + if (I != TIMap.end()) + return I->second; - // This call can invalidate MemoizedTypeInfo[T], so we need a second lookup. - TypeInfo TI = getTypeInfoImpl(T); - MemoizedTypeInfo[T] = TI; - return TI; + // This call can invalidate MemoizedTypeInfo[T], so we need a second lookup. + TypeInfo TI = getTypeInfoImpl(T, NeedsPreferredAlignment); + TIMap[T] = TI; + return TI; + }; + + return NeedsPreferredAlignment ? getTypeInfo(MemoizedPreferredTypeInfo) + : getTypeInfo(MemoizedTypeInfo); } static unsigned getSveVectorWidth(const Type *T) { @@ -1918,14 +1929,24 @@ /// getTypeInfoImpl - Return the size of the specified type, in bits. This /// method does not work on incomplete types. /// +/// Set "NeedsPreferredAlignment" as true only when allocating memory for a +/// variable on the stack or in global/thread local memory. The preferred +/// alignment applies only to a complete object. +/// /// FIXME: Pointers into different addr spaces could have different sizes and /// alignment requirements: getPointerInfo should take an AddrSpace, this /// should take a QualType, &c. -TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { +TypeInfo ASTContext::getTypeInfoImpl(const Type *T, + bool NeedsPreferredAlignment) const { uint64_t Width = 0; unsigned Align = 8; bool AlignIsRequired = false; unsigned AS = 0; + + auto setAlign = [&](unsigned PreferredAlignment, unsigned Alignment) { + Align = NeedsPreferredAlignment ? PreferredAlignment : Alignment; + }; + switch (T->getTypeClass()) { #define TYPE(Class, Base) #define ABSTRACT_TYPE(Class, Base) @@ -1933,8 +1954,9 @@ #define DEPENDENT_TYPE(Class, Base) case Type::Class: #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) \ case Type::Class: \ - assert(!T->isDependentType() && "should not see dependent types here"); \ - return getTypeInfo(cast(T)->desugar().getTypePtr()); + assert(!T->isDependentType() && "should not see dependent types here"); \ + return getTypeInfo(cast(T)->desugar().getTypePtr(), \ + NeedsPreferredAlignment); #include "clang/AST/TypeNodes.inc" llvm_unreachable("Should not see dependent types"); @@ -1953,7 +1975,8 @@ if (const auto *CAT = dyn_cast(T)) Size = CAT->getSize().getZExtValue(); - TypeInfo EltInfo = getTypeInfo(cast(T)->getElementType()); + TypeInfo EltInfo = getTypeInfo(cast(T)->getElementType(), + NeedsPreferredAlignment); assert((Size == 0 || EltInfo.Width <= (uint64_t)(-1) / Size) && "Overflow in array type bit size evaluation"); Width = EltInfo.Width * Size; @@ -1968,7 +1991,8 @@ case Type::ExtVector: case Type::Vector: { const auto *VT = cast(T); - TypeInfo EltInfo = getTypeInfo(VT->getElementType()); + TypeInfo EltInfo = + getTypeInfo(VT->getElementType(), NeedsPreferredAlignment); Width = EltInfo.Width * VT->getNumElements(); Align = Width; // If the alignment is not a power of 2, round up to the next power of 2. @@ -1986,7 +2010,8 @@ case Type::ConstantMatrix: { const auto *MT = cast(T); - TypeInfo ElementInfo = getTypeInfo(MT->getElementType()); + TypeInfo ElementInfo = + getTypeInfo(MT->getElementType(), NeedsPreferredAlignment); // The internal layout of a matrix value is implementation defined. // Initially be ABI compatible with arrays with respect to alignment and // size. @@ -2118,17 +2143,17 @@ break; case BuiltinType::Double: Width = Target->getDoubleWidth(); - Align = Target->getDoubleAlign(); + setAlign(Width, Target->getDoubleAlign()); break; case BuiltinType::LongDouble: if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && (Target->getLongDoubleWidth() != AuxTarget->getLongDoubleWidth() || Target->getLongDoubleAlign() != AuxTarget->getLongDoubleAlign())) { Width = AuxTarget->getLongDoubleWidth(); - Align = AuxTarget->getLongDoubleAlign(); + setAlign(Width, AuxTarget->getLongDoubleAlign()); } else { Width = Target->getLongDoubleWidth(); - Align = Target->getLongDoubleAlign(); + setAlign(Width, Target->getLongDoubleAlign()); } break; case BuiltinType::Float128: @@ -2223,16 +2248,19 @@ case Type::Complex: { // Complex types have the same alignment as their elements, but twice the // size. - TypeInfo EltInfo = getTypeInfo(cast(T)->getElementType()); + TypeInfo EltInfo = getTypeInfo(cast(T)->getElementType(), + NeedsPreferredAlignment); Width = EltInfo.Width * 2; Align = EltInfo.Align; break; } case Type::ObjCObject: - return getTypeInfo(cast(T)->getBaseType().getTypePtr()); + return getTypeInfo(cast(T)->getBaseType().getTypePtr(), + NeedsPreferredAlignment); case Type::Adjusted: case Type::Decayed: - return getTypeInfo(cast(T)->getAdjustedType().getTypePtr()); + return getTypeInfo(cast(T)->getAdjustedType().getTypePtr(), + NeedsPreferredAlignment); case Type::ObjCInterface: { const auto *ObjCI = cast(T); if (ObjCI->getDecl()->isInvalidDecl()) { @@ -2267,7 +2295,8 @@ if (const auto *ET = dyn_cast(TT)) { const EnumDecl *ED = ET->getDecl(); TypeInfo Info = - getTypeInfo(ED->getIntegerType()->getUnqualifiedDesugaredType()); + getTypeInfo(ED->getIntegerType()->getUnqualifiedDesugaredType(), + NeedsPreferredAlignment); if (unsigned AttrAlign = ED->getMaxAlignment()) { Info.Align = AttrAlign; Info.AlignIsRequired = true; @@ -2279,36 +2308,43 @@ const RecordDecl *RD = RT->getDecl(); const ASTRecordLayout &Layout = getASTRecordLayout(RD); Width = toBits(Layout.getSize()); - Align = toBits(Layout.getAlignment()); + setAlign(toBits(Layout.getPreferredAlignment()), + toBits(Layout.getAlignment())); AlignIsRequired = RD->hasAttr(); break; } case Type::SubstTemplateTypeParm: - return getTypeInfo(cast(T)-> - getReplacementType().getTypePtr()); + return getTypeInfo( + cast(T)->getReplacementType().getTypePtr(), + NeedsPreferredAlignment); case Type::Auto: case Type::DeducedTemplateSpecialization: { const auto *A = cast(T); assert(!A->getDeducedType().isNull() && "cannot request the size of an undeduced or dependent auto type"); - return getTypeInfo(A->getDeducedType().getTypePtr()); + return getTypeInfo(A->getDeducedType().getTypePtr(), + NeedsPreferredAlignment); } case Type::Paren: - return getTypeInfo(cast(T)->getInnerType().getTypePtr()); + return getTypeInfo(cast(T)->getInnerType().getTypePtr(), + NeedsPreferredAlignment); case Type::MacroQualified: return getTypeInfo( - cast(T)->getUnderlyingType().getTypePtr()); + cast(T)->getUnderlyingType().getTypePtr(), + NeedsPreferredAlignment); case Type::ObjCTypeParam: - return getTypeInfo(cast(T)->desugar().getTypePtr()); + return getTypeInfo(cast(T)->desugar().getTypePtr(), + NeedsPreferredAlignment); case Type::Typedef: { const TypedefNameDecl *Typedef = cast(T)->getDecl(); - TypeInfo Info = getTypeInfo(Typedef->getUnderlyingType().getTypePtr()); + TypeInfo Info = getTypeInfo(Typedef->getUnderlyingType().getTypePtr(), + NeedsPreferredAlignment); // If the typedef has an aligned attribute on it, it overrides any computed // alignment we have. This violates the GCC documentation (which says that // attribute(aligned) can only round up) but matches its implementation. @@ -2327,15 +2363,18 @@ } case Type::Elaborated: - return getTypeInfo(cast(T)->getNamedType().getTypePtr()); + return getTypeInfo(cast(T)->getNamedType().getTypePtr(), + NeedsPreferredAlignment); case Type::Attributed: return getTypeInfo( - cast(T)->getEquivalentType().getTypePtr()); + cast(T)->getEquivalentType().getTypePtr(), + NeedsPreferredAlignment); case Type::Atomic: { // Start with the base type information. - TypeInfo Info = getTypeInfo(cast(T)->getValueType()); + TypeInfo Info = getTypeInfo(cast(T)->getValueType(), + NeedsPreferredAlignment); Width = Info.Width; Align = Info.Align; @@ -2383,7 +2422,8 @@ const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl()); UnadjustedAlign = toBits(Layout.getUnadjustedAlignment()); } else { - UnadjustedAlign = getTypeAlign(T->getUnqualifiedDesugaredType()); + UnadjustedAlign = getTypeAlign(T->getUnqualifiedDesugaredType(), + false /* NeedsPreferredAlignment */); } MemoizedUnadjustedAlign[T] = UnadjustedAlign; @@ -2414,19 +2454,23 @@ /// getTypeSizeInChars - Return the size of the specified type, in characters. /// This method does not work on incomplete types. CharUnits ASTContext::getTypeSizeInChars(QualType T) const { - return getTypeInfoInChars(T).first; + return getTypeInfoInChars(T, false /* NeedsPreferredAlignment */).first; } CharUnits ASTContext::getTypeSizeInChars(const Type *T) const { - return getTypeInfoInChars(T).first; + return getTypeInfoInChars(T, false /* NeedsPreferredAlignment */).first; } -/// getTypeAlignInChars - Return the ABI-specified alignment of a type, in -/// characters. This method does not work on incomplete types. -CharUnits ASTContext::getTypeAlignInChars(QualType T) const { - return toCharUnitsFromBits(getTypeAlign(T)); +/// getTypeAlignInChars - Set "NeedsPreferredAlignment" as true to return the +/// preferred alignment of a complete type \p T only when allocating memory for +/// a variable on the the stack or in global/thread local memory. Otherwise, +/// return the ABI-specified alignment of a (complete) type \p T, in characters. +CharUnits ASTContext::getTypeAlignInChars(QualType T, + bool NeedsPreferredAlignment) const { + return toCharUnitsFromBits(getTypeAlign(T, NeedsPreferredAlignment)); } -CharUnits ASTContext::getTypeAlignInChars(const Type *T) const { - return toCharUnitsFromBits(getTypeAlign(T)); +CharUnits ASTContext::getTypeAlignInChars(const Type *T, + bool NeedsPreferredAlignment) const { + return toCharUnitsFromBits(getTypeAlign(T, NeedsPreferredAlignment)); } /// getTypeUnadjustedAlignInChars - Return the ABI-specified alignment of a @@ -2444,7 +2488,7 @@ /// alignment in cases where it is beneficial for performance or backwards /// compatibility preserving to overalign a data type. unsigned ASTContext::getPreferredTypeAlign(const Type *T) const { - TypeInfo TI = getTypeInfo(T); + TypeInfo TI = getTypeInfo(T, false /* NeedsPreferredAlignment */); unsigned ABIAlign = TI.Align; T = T->getBaseElementTypeUnsafe(); @@ -2498,7 +2542,8 @@ /// to a global variable of the specified type. unsigned ASTContext::getAlignOfGlobalVar(QualType T) const { uint64_t TypeSize = getTypeSize(T.getTypePtr()); - return std::max(getTypeAlign(T), getTargetInfo().getMinGlobalAlign(TypeSize)); + return std::max(getTypeAlign(T, true /* NeedsPreferredAlignment */), + getTargetInfo().getMinGlobalAlign(TypeSize)); } /// getAlignOfGlobalVarInChars - Return the alignment in characters that @@ -5188,7 +5233,7 @@ // Apply the protocol qualifers. bool hasError; Canonical = getCanonicalType(applyObjCProtocolQualifiers( - Canonical, protocols, hasError, true /*allowOnPointerType*/)); + Canonical, protocols, hasError, true/*allowOnPointerType*/)); assert(!hasError && "Error when apply protocol qualifier to bound type"); } @@ -6837,7 +6882,7 @@ // Encode result type. if (getLangOpts().EncodeExtendedBlockSig) getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None, BlockReturnTy, S, - true /*Extended*/); + true/*Extended*/); else getObjCEncodingForType(BlockReturnTy, S); // Compute size of all parameters. @@ -6872,7 +6917,7 @@ PType = PVDecl->getType(); if (getLangOpts().EncodeExtendedBlockSig) getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None, PType, - S, true /*Extended*/); + S, true/*Extended*/); else getObjCEncodingForType(PType, S); S += charUnitsToString(ParmOffset); @@ -10987,7 +11032,8 @@ QualType AtomicTy = E->getPtr()->getType()->getPointeeType(); CharUnits sizeChars = getTypeSizeInChars(AtomicTy); uint64_t Size = sizeChars.getQuantity(); - CharUnits alignChars = getTypeAlignInChars(AtomicTy); + CharUnits alignChars = + getTypeAlignInChars(AtomicTy, false /* NeedsPreferredAlignment */); unsigned Align = alignChars.getQuantity(); unsigned MaxInlineWidthInBits = getTargetInfo().getMaxAtomicInlineWidth(); return (Size != Align || toBits(sizeChars) > MaxInlineWidthInBits); diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -264,7 +264,8 @@ ConstantExpr::ResultStorageKind ConstantExpr::getStorageKind(const Type *T, const ASTContext &Context) { - if (T->isIntegralOrEnumerationType() && Context.getTypeInfo(T).Width <= 64) + if (T->isIntegralOrEnumerationType() && + Context.getTypeInfo(T, false /* NeedsPreferredAlignment */).Width <= 64) return ConstantExpr::RSK_Int64; return ConstantExpr::RSK_APValue; } @@ -901,7 +902,8 @@ : Expr(FixedPointLiteralClass, type, VK_RValue, OK_Ordinary), Loc(l), Scale(Scale) { assert(type->isFixedPointType() && "Illegal type in FixedPointLiteral"); - assert(V.getBitWidth() == C.getTypeInfo(type).Width && + assert(V.getBitWidth() == + C.getTypeInfo(type, false /* NeedsPreferredAlignment */).Width && "Fixed point type is not the correct size for constant."); setValue(C, V); setDependence(ExprDependence::None); diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -8484,7 +8484,8 @@ Info.Ctx.getPreferredTypeAlign(T.getTypePtr())); // alignof and _Alignof are defined to return the ABI alignment. else if (ExprKind == UETT_AlignOf) - return Info.Ctx.getTypeAlignInChars(T.getTypePtr()); + return Info.Ctx.getTypeAlignInChars(T.getTypePtr(), + false /* NeedsPreferredAlignment */); else llvm_unreachable("GetAlignOfType on a non-alignment ExprKind"); } @@ -11596,7 +11597,8 @@ QualType PointeeType = E->getArg(1)->IgnoreImpCasts()->getType()-> castAs()->getPointeeType(); if (!PointeeType->isIncompleteType() && - Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) { + Info.Ctx.getTypeAlignInChars( + PointeeType, false /* NeedsPreferredAlignment */) >= Size) { // OK, we will inline operations on this object. return Success(1, E); } diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -1477,7 +1477,8 @@ } assert(!Type.isNull() && "Did not find a type!"); - CharUnits TypeAlign = Context.getTypeAlignInChars(Type); + CharUnits TypeAlign = + Context.getTypeAlignInChars(Type, false /* NeedsPreferredAlignment */); // We're not going to use any of the unfilled bits in the last byte. UnfilledBitsInLastUnit = 0; @@ -1519,7 +1520,8 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { bool FieldPacked = Packed || D->hasAttr(); uint64_t FieldSize = D->getBitWidthValue(Context); - TypeInfo FieldInfo = Context.getTypeInfo(D->getType()); + TypeInfo FieldInfo = + Context.getTypeInfo(D->getType(), false /* NeedsPreferredAlignment */); uint64_t TypeSize = FieldInfo.Width; unsigned FieldAlign = FieldInfo.Align; @@ -1838,13 +1840,16 @@ CharUnits EffectiveFieldSize; auto setDeclInfo = [&](bool IsIncompleteArrayType) { - auto TI = Context.getTypeInfoInChars(D->getType()); + auto TI = Context.getTypeInfoInChars(D->getType(), + false /* NeedsPreferredAlignment */); FieldAlign = TI.second; // Flexible array members don't have any size, but they have to be // aligned appropriately for their element type. EffectiveFieldSize = FieldSize = IsIncompleteArrayType ? CharUnits::Zero() : TI.first; - AlignIsRequired = Context.getTypeInfo(D->getType()).AlignIsRequired; + AlignIsRequired = + Context.getTypeInfo(D->getType(), false /* NeedsPreferredAlignment */) + .AlignIsRequired; }; if (D->getType()->isIncompleteArrayType()) { @@ -2572,14 +2577,17 @@ // alignment attributes. ElementInfo Info; std::tie(Info.Size, Info.Alignment) = - Context.getTypeInfoInChars(FD->getType()->getUnqualifiedDesugaredType()); + Context.getTypeInfoInChars(FD->getType()->getUnqualifiedDesugaredType(), + false /* NeedsPreferredAlignment */); // Respect align attributes on the field. CharUnits FieldRequiredAlignment = Context.toCharUnitsFromBits(FD->getMaxAlignment()); // Respect align attributes on the type. if (Context.isAlignmentRequired(FD->getType())) - FieldRequiredAlignment = std::max( - Context.getTypeAlignInChars(FD->getType()), FieldRequiredAlignment); + FieldRequiredAlignment = + std::max(Context.getTypeAlignInChars( + FD->getType(), false /* NeedsPreferredAlignment */), + FieldRequiredAlignment); // Respect attributes applied to subobjects of the field. if (FD->isBitField()) // For some reason __declspec align impacts alignment rather than required diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -55,11 +55,13 @@ uint64_t ValueAlignInBits; uint64_t AtomicAlignInBits; - TypeInfo ValueTI = C.getTypeInfo(ValueTy); + TypeInfo ValueTI = + C.getTypeInfo(ValueTy, false /* NeedsPreferredAlignment */); ValueSizeInBits = ValueTI.Width; ValueAlignInBits = ValueTI.Align; - TypeInfo AtomicTI = C.getTypeInfo(AtomicTy); + TypeInfo AtomicTI = + C.getTypeInfo(AtomicTy, false /* NeedsPreferredAlignment */); AtomicSizeInBits = AtomicTI.Width; AtomicAlignInBits = AtomicTI.Align; @@ -768,7 +770,8 @@ SourceLocation Loc, CharUnits SizeInChars) { if (UseOptimizedLibcall) { // Load value and pass it to the function directly. - CharUnits Align = CGF.getContext().getTypeAlignInChars(ValTy); + CharUnits Align = CGF.getContext().getTypeAlignInChars( + ValTy, false /* NeedsPreferredAlignment */); int64_t SizeInBits = CGF.getContext().toBits(SizeInChars); ValTy = CGF.getContext().getIntTypeForBitwidth(SizeInBits, /*Signed=*/false); @@ -807,7 +810,8 @@ } CharUnits sizeChars, alignChars; - std::tie(sizeChars, alignChars) = getContext().getTypeInfoInChars(AtomicTy); + std::tie(sizeChars, alignChars) = getContext().getTypeInfoInChars( + AtomicTy, true /* NeedsPreferredAlignment */); uint64_t Size = sizeChars.getQuantity(); unsigned MaxInlineWidthInBits = getTarget().getMaxAtomicInlineWidth(); diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -557,8 +557,8 @@ // Theoretically, this could be in a different address space, so // don't assume standard pointer size/align. llvm::Type *llvmType = CGM.getTypes().ConvertType(thisType); - std::pair tinfo - = CGM.getContext().getTypeInfoInChars(thisType); + std::pair tinfo = CGM.getContext().getTypeInfoInChars( + thisType, false /* NeedsPreferredAlignment */); maxFieldAlign = std::max(maxFieldAlign, tinfo.second); layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first, diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -590,9 +590,13 @@ getIntegerWidthAndSignedness(const clang::ASTContext &context, const clang::QualType Type) { assert(Type->isIntegerType() && "Given type is not an integer."); - unsigned Width = Type->isBooleanType() ? 1 - : Type->isExtIntType() ? context.getIntWidth(Type) - : context.getTypeInfo(Type).Width; + unsigned Width = + Type->isBooleanType() + ? 1 + : Type->isExtIntType() + ? context.getIntWidth(Type) + : context.getTypeInfo(Type, false /* NeedsPreferredAlignment */) + .Width; bool Signed = Type->isSignedIntegerType(); return {Width, Signed}; } @@ -2767,8 +2771,8 @@ SrcPhi->addIncoming(Src, Entry); PHINode *SizePhi = Builder.CreatePHI(SizeTy, 2); SizePhi->addIncoming(Size, Entry); - CharUnits WCharAlign = - getContext().getTypeAlignInChars(getContext().WCharTy); + CharUnits WCharAlign = getContext().getTypeAlignInChars( + getContext().WCharTy, false /* NeedsPreferredAlignment */); Value *DstCh = Builder.CreateAlignedLoad(WCharTy, DstPhi, WCharAlign); Value *SrcCh = Builder.CreateAlignedLoad(WCharTy, SrcPhi, WCharAlign); Value *DstGtSrc = Builder.CreateICmpUGT(DstCh, SrcCh); @@ -12106,7 +12110,10 @@ case X86::BI__builtin_ia32_storeapd512_mask: return EmitX86MaskedStore( *this, Ops, - getContext().getTypeAlignInChars(E->getArg(1)->getType()).getAsAlign()); + getContext() + .getTypeAlignInChars(E->getArg(1)->getType(), + false /* NeedsPreferredAlignment */) + .getAsAlign()); case X86::BI__builtin_ia32_loadups128_mask: case X86::BI__builtin_ia32_loadups256_mask: @@ -12146,7 +12153,10 @@ case X86::BI__builtin_ia32_movdqa64load512_mask: return EmitX86MaskedLoad( *this, Ops, - getContext().getTypeAlignInChars(E->getArg(1)->getType()).getAsAlign()); + getContext() + .getTypeAlignInChars(E->getArg(1)->getType(), + false /* NeedsPreferredAlignment */) + .getAsAlign()); case X86::BI__builtin_ia32_expandloaddf128_mask: case X86::BI__builtin_ia32_expandloaddf256_mask: @@ -14020,7 +14030,9 @@ Value *Ptr = Builder.CreateIntToPtr(Ops[0], llvm::PointerType::get(IntTy, 257)); LoadInst *Load = Builder.CreateAlignedLoad( - IntTy, Ptr, getContext().getTypeAlignInChars(E->getType())); + IntTy, Ptr, + getContext().getTypeAlignInChars(E->getType(), + false /* NeedsPreferredAlignment */)); Load->setVolatile(true); return Load; } @@ -14032,7 +14044,9 @@ Value *Ptr = Builder.CreateIntToPtr(Ops[0], llvm::PointerType::get(IntTy, 256)); LoadInst *Load = Builder.CreateAlignedLoad( - IntTy, Ptr, getContext().getTypeAlignInChars(E->getType())); + IntTy, Ptr, + getContext().getTypeAlignInChars(E->getType(), + false /* NeedsPreferredAlignment */)); Load->setVolatile(true); return Load; } diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp --- a/clang/lib/CodeGen/CGCUDANV.cpp +++ b/clang/lib/CodeGen/CGCUDANV.cpp @@ -355,8 +355,8 @@ CharUnits Offset = CharUnits::Zero(); for (const VarDecl *A : Args) { CharUnits TyWidth, TyAlign; - std::tie(TyWidth, TyAlign) = - CGM.getContext().getTypeInfoInChars(A->getType()); + std::tie(TyWidth, TyAlign) = CGM.getContext().getTypeInfoInChars( + A->getType(), false /* NeedsPreferredAlignment */); Offset = Offset.alignTo(TyAlign); llvm::Value *Args[] = { CGF.Builder.CreatePointerCast(CGF.GetAddrOfLocalVar(A).getPointer(), diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2271,7 +2271,8 @@ // Add 'dereferenceable' and 'alignment'. auto PTy = ParamType->getPointeeType(); if (!PTy->isIncompleteType() && PTy->isConstantSizeType()) { - auto info = getContext().getTypeInfoInChars(PTy); + auto info = getContext().getTypeInfoInChars( + PTy, false /* NeedsPreferredAlignment */); Attrs.addDereferenceableAttr(info.first.getQuantity()); Attrs.addAlignmentAttr(info.second.getAsAlign()); } @@ -2447,7 +2448,8 @@ Builder.CreateStructGEP(ArgStruct, FieldIndex, Arg->getName()); if (ArgI.getInAllocaIndirect()) V = Address(Builder.CreateLoad(V), - getContext().getTypeAlignInChars(Ty)); + getContext().getTypeAlignInChars( + Ty, false /* NeedsPreferredAlignment */)); ArgVals.push_back(ParamValue::forIndirect(V)); break; } @@ -2595,7 +2597,9 @@ assert(pointeeTy->isPointerType()); Address temp = CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp"); - Address arg = Address(V, getContext().getTypeAlignInChars(pointeeTy)); + Address arg = + Address(V, getContext().getTypeAlignInChars( + pointeeTy, false /* NeedsPreferredAlignment */)); llvm::Value *incomingErrorValue = Builder.CreateLoad(arg); Builder.CreateStore(incomingErrorValue, temp); V = temp.getPointer(); @@ -4420,7 +4424,9 @@ // Make a temporary alloca and store the address of it into the argument // struct. Address Addr = CreateMemTempWithoutCast( - I->Ty, getContext().getTypeAlignInChars(I->Ty), + I->Ty, + getContext().getTypeAlignInChars( + I->Ty, false /* NeedsPreferredAlignment */), "indirect-arg-temp"); I->copyInto(*this, Addr); Address ArgSlot = @@ -4484,7 +4490,9 @@ auto AS = LV.getAddressSpace(); if (!ArgInfo.getIndirectByVal() || - (LV.getAlignment() < getContext().getTypeAlignInChars(I->Ty))) { + (LV.getAlignment() < + getContext().getTypeAlignInChars( + I->Ty, false /* NeedsPreferredAlignment */))) { NeedCopy = true; } if (!getLangOpts().OpenCL) { @@ -4559,7 +4567,8 @@ QualType pointeeTy = I->Ty->getPointeeType(); swiftErrorArg = - Address(V, getContext().getTypeAlignInChars(pointeeTy)); + Address(V, getContext().getTypeAlignInChars( + pointeeTy, false /* NeedsPreferredAlignment */)); swiftErrorTemp = CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp"); diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -798,8 +798,8 @@ size_t NumFields = 0; for (const auto *Field : ClassDecl->fields()) { const FieldDecl *D = Field; - std::pair FieldInfo = - Context.getTypeInfoInChars(D->getType()); + std::pair FieldInfo = Context.getTypeInfoInChars( + D->getType(), false /* NeedsPreferredAlignment */); CharUnits FieldSize = FieldInfo.first; assert(NumFields < SSV.size()); SSV[NumFields].Size = D->isBitField() ? 0 : FieldSize.getQuantity(); diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -51,7 +51,7 @@ using namespace clang::CodeGen; static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx) { - auto TI = Ctx.getTypeInfo(Ty); + auto TI = Ctx.getTypeInfo(Ty, false /* NeedsPreferredAlignment */); return TI.AlignIsRequired ? TI.Align : 0; } @@ -1099,7 +1099,8 @@ EltTys.push_back(CreateMemberType(Unit, FType, "__FuncPtr", &FieldOffset)); FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy); uint64_t FieldSize = CGM.getContext().getTypeSize(Ty); - uint32_t FieldAlign = CGM.getContext().getTypeAlign(Ty); + uint32_t FieldAlign = + CGM.getContext().getTypeAlign(Ty, false /* NeedsPreferredAlignment */); EltTys.push_back(DBuilder.createMemberType( Unit, "__descriptor", nullptr, LineNo, FieldSize, FieldAlign, FieldOffset, llvm::DINode::FlagZero, DescTy)); @@ -1331,7 +1332,8 @@ uint64_t SizeInBits = 0; auto Align = AlignInBits; if (!type->isIncompleteArrayType()) { - TypeInfo TI = CGM.getContext().getTypeInfo(type); + TypeInfo TI = + CGM.getContext().getTypeInfo(type, false /* NeedsPreferredAlignment */); SizeInBits = TI.Width; if (!Align) Align = getTypeAlignIfRequired(type, CGM.getContext()); @@ -4503,7 +4505,8 @@ llvm::DIType *fieldType; if (capture->isByRef()) { - TypeInfo PtrInfo = C.getTypeInfo(C.VoidPtrTy); + TypeInfo PtrInfo = + C.getTypeInfo(C.VoidPtrTy, false /* NeedsPreferredAlignment */); auto Align = PtrInfo.AlignIsRequired ? PtrInfo.Align : 0; // FIXME: This recomputes the layout of the BlockByRefWrapper. uint64_t xoffset; diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1732,7 +1732,8 @@ llvm::Type *ElTy = Loc.getElementType(); llvm::Constant *Constant = constWithPadding( CGM, IsPattern::Yes, initializationPatternFor(CGM, ElTy)); - CharUnits ConstantAlign = getContext().getTypeAlignInChars(VlaSize.Type); + CharUnits ConstantAlign = getContext().getTypeAlignInChars( + VlaSize.Type, false /* NeedsPreferredAlignment */); llvm::BasicBlock *SetupBB = createBasicBlock("vla-setup.loop"); llvm::BasicBlock *LoopBB = createBasicBlock("vla-init.loop"); llvm::BasicBlock *ContBB = createBasicBlock("vla-init.cont"); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -138,14 +138,18 @@ } Address CodeGenFunction::CreateIRTemp(QualType Ty, const Twine &Name) { - CharUnits Align = getContext().getTypeAlignInChars(Ty); + CharUnits Align = + getContext().getTypeAlignInChars(Ty, false /* NeedsPreferredAlignment */); return CreateTempAlloca(ConvertType(Ty), Align, Name); } Address CodeGenFunction::CreateMemTemp(QualType Ty, const Twine &Name, Address *Alloca) { // FIXME: Should we prefer the preferred type alignment here? - return CreateMemTemp(Ty, getContext().getTypeAlignInChars(Ty), Name, Alloca); + return CreateMemTemp( + Ty, + getContext().getTypeAlignInChars(Ty, false /* NeedsPreferredAlignment */), + Name, Alloca); } Address CodeGenFunction::CreateMemTemp(QualType Ty, CharUnits Align, @@ -172,8 +176,10 @@ Address CodeGenFunction::CreateMemTempWithoutCast(QualType Ty, const Twine &Name) { - return CreateMemTempWithoutCast(Ty, getContext().getTypeAlignInChars(Ty), - Name); + return CreateMemTempWithoutCast( + Ty, + getContext().getTypeAlignInChars(Ty, false /* NeedsPreferredAlignment */), + Name); } /// EvaluateExprAsBool - Perform the usual unary conversions on the specified @@ -408,7 +414,8 @@ llvm::GlobalValue::PrivateLinkage, Init, ".ref.tmp", nullptr, llvm::GlobalValue::NotThreadLocal, CGF.getContext().getTargetAddressSpace(AS)); - CharUnits alignment = CGF.getContext().getTypeAlignInChars(Ty); + CharUnits alignment = CGF.getContext().getTypeAlignInChars( + Ty, false /* NeedsPreferredAlignment */); GV->setAlignment(alignment.getAsAlign()); llvm::Constant *C = GV; if (AS != LangAS::Default) diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -507,7 +507,8 @@ /* InsertBefore= */ nullptr, llvm::GlobalVariable::NotThreadLocal, CGM.getContext().getTargetAddressSpace(AS)); Emitter.finalize(GV); - CharUnits Align = CGM.getContext().getTypeAlignInChars(ArrayQTy); + CharUnits Align = CGM.getContext().getTypeAlignInChars( + ArrayQTy, false /* NeedsPreferredAlignment */); GV->setAlignment(Align.getAsAlign()); EmitFinalDestCopy(ArrayQTy, CGF.MakeAddrLValue(GV, ArrayQTy, Align)); return; @@ -1978,7 +1979,8 @@ if (MayOverlap) TypeInfo = getContext().getTypeInfoDataSizeInChars(Ty); else - TypeInfo = getContext().getTypeInfoInChars(Ty); + TypeInfo = getContext().getTypeInfoInChars( + Ty, false /* NeedsPreferredAlignment */); llvm::Value *SizeVal = nullptr; if (TypeInfo.first.isZero()) { @@ -1987,7 +1989,8 @@ getContext().getAsArrayType(Ty))) { QualType BaseEltTy; SizeVal = emitArrayLength(VAT, BaseEltTy, DestPtr); - TypeInfo = getContext().getTypeInfoInChars(BaseEltTy); + TypeInfo = getContext().getTypeInfoInChars( + BaseEltTy, false /* NeedsPreferredAlignment */); assert(!TypeInfo.first.isZero()); SizeVal = Builder.CreateNUWMul( SizeVal, diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -1570,7 +1570,8 @@ llvm::Value *allocSize = EmitCXXNewAllocSize(*this, E, minElements, numElements, allocSizeWithoutCookie); - CharUnits allocAlign = getContext().getTypeAlignInChars(allocType); + CharUnits allocAlign = getContext().getTypeAlignInChars( + allocType, true /* NeedsPreferredAlignment */); // Emit the allocation call. If the allocator is a global placement // operator, just "inline" it directly. @@ -1820,8 +1821,9 @@ // Pass the alignment if the delete function has an align_val_t parameter. if (Params.Alignment) { QualType AlignValType = *ParamTypeIt++; - CharUnits DeleteTypeAlign = getContext().toCharUnitsFromBits( - getContext().getTypeAlignIfKnown(DeleteTy)); + CharUnits DeleteTypeAlign = + getContext().toCharUnitsFromBits(getContext().getTypeAlignIfKnown( + DeleteTy, true /* NeedsPreferredAlignment */)); llvm::Value *Align = llvm::ConstantInt::get(ConvertType(AlignValType), DeleteTypeAlign.getQuantity()); DeleteArgs.add(RValue::get(Align), AlignValType); diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -896,7 +896,8 @@ static ConstantAddress tryEmitGlobalCompoundLiteral(CodeGenModule &CGM, CodeGenFunction *CGF, const CompoundLiteralExpr *E) { - CharUnits Align = CGM.getContext().getTypeAlignInChars(E->getType()); + CharUnits Align = CGM.getContext().getTypeAlignInChars( + E->getType(), false /* NeedsPreferredAlignment */); if (llvm::GlobalVariable *Addr = CGM.getAddrOfConstantCompoundLiteralIfEmitted(E)) return ConstantAddress(Addr, Align); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -419,7 +419,8 @@ if (Value *Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) { if (E->isGLValue()) return CGF.Builder.CreateLoad(Address( - Result, CGF.getContext().getTypeAlignInChars(E->getType()))); + Result, CGF.getContext().getTypeAlignInChars( + E->getType(), false /* NeedsPreferredAlignment */))); return Result; } return Visit(E->getSubExpr()); diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -850,8 +850,8 @@ // Evaluate the ivar's size and alignment. ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl(); QualType ivarType = ivar->getType(); - std::tie(IvarSize, IvarAlignment) = - CGM.getContext().getTypeInfoInChars(ivarType); + std::tie(IvarSize, IvarAlignment) = CGM.getContext().getTypeInfoInChars( + ivarType, false /* NeedsPreferredAlignment */); // If we have a copy property, we always have to use getProperty/setProperty. // TODO: we could actually use setProperty and an expression for non-atomics. @@ -3704,8 +3704,8 @@ SourceLocation()); RValue DV = EmitAnyExpr(&DstExpr); - CharUnits Alignment - = getContext().getTypeAlignInChars(TheCXXConstructExpr->getType()); + CharUnits Alignment = getContext().getTypeAlignInChars( + TheCXXConstructExpr->getType(), false /* NeedsPreferredAlignment */); EmitAggExpr(TheCXXConstructExpr, AggValueSlot::forAddr(Address(DV.getScalarVal(), Alignment), Qualifiers(), diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -1870,7 +1870,10 @@ CGM.getContext().getTypeSizeInChars(ivarTy).getQuantity()); // Alignment will be stored as a base-2 log of the alignment. unsigned align = - llvm::Log2_32(Context.getTypeAlignInChars(ivarTy).getQuantity()); + llvm::Log2_32(Context + .getTypeAlignInChars( + ivarTy, false /* NeedsPreferredAlignment */) + .getQuantity()); // Objects that require more than 2^64-byte alignment should be impossible! assert(align < 64); // uint32_t flags; diff --git a/clang/lib/CodeGen/CGOpenCLRuntime.cpp b/clang/lib/CodeGen/CGOpenCLRuntime.cpp --- a/clang/lib/CodeGen/CGOpenCLRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenCLRuntime.cpp @@ -109,9 +109,11 @@ const PipeType *PipeTy = PipeArg->getType()->castAs(); // The type of the last (implicit) argument to be passed. llvm::Type *Int32Ty = llvm::IntegerType::getInt32Ty(CGM.getLLVMContext()); - unsigned TypeSize = CGM.getContext() - .getTypeAlignInChars(PipeTy->getElementType()) - .getQuantity(); + unsigned TypeSize = + CGM.getContext() + .getTypeAlignInChars(PipeTy->getElementType(), + false /* NeedsPreferredAlignment */) + .getQuantity(); return llvm::ConstantInt::get(Int32Ty, TypeSize, false); } diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -1991,7 +1991,8 @@ if (CGM.getLangOpts().OpenMP && CGM.getLangOpts().OpenMPUseTLS && CGM.getTarget().isTLSSupported()) { cast(GAddr)->setThreadLocal(/*Val=*/true); - return Address(GAddr, CGM.getContext().getTypeAlignInChars(VarType)); + return Address(GAddr, CGM.getContext().getTypeAlignInChars( + VarType, false /* NeedsPreferredAlignment */)); } std::string CacheSuffix = getName({"cache", ""}); llvm::Value *Args[] = { @@ -2009,7 +2010,8 @@ CGM.getModule(), OMPRTL___kmpc_threadprivate_cached), Args), VarLVType->getPointerTo(/*AddrSpace=*/0)), - CGM.getContext().getTypeAlignInChars(VarType)); + CGM.getContext().getTypeAlignInChars( + VarType, false /* NeedsPreferredAlignment */)); } void CGOpenMPRuntime::emitIfClause(CodeGenFunction &CGF, const Expr *Cond, @@ -4892,7 +4894,8 @@ // It is required to handle depobj(x) update(in) construct. // kmp_depend_info[] deps; llvm::Value *NumDepsVal; - CharUnits Align = C.getTypeAlignInChars(KmpDependInfoTy); + CharUnits Align = C.getTypeAlignInChars(KmpDependInfoTy, + false /* NeedsPreferredAlignment */); if (const auto *IE = cast_or_null(Dependencies.IteratorExpr)) { NumDepsVal = llvm::ConstantInt::get(CGF.SizeTy, 1); @@ -7505,9 +7508,10 @@ BP = CGF.EmitOMPSharedLValue(AssocExpr).getAddress(CGF); } else if (OAShE && isa(OAShE->getBase()->IgnoreParenCasts())) { - BP = Address( - CGF.EmitScalarExpr(OAShE->getBase()), - CGF.getContext().getTypeAlignInChars(OAShE->getBase()->getType())); + BP = Address(CGF.EmitScalarExpr(OAShE->getBase()), + CGF.getContext().getTypeAlignInChars( + OAShE->getBase()->getType(), + false /* NeedsPreferredAlignment */)); } else { // The base is the reference to the variable. // BP = &Var. @@ -7634,7 +7638,8 @@ if (OAShE) { LB = Address(CGF.EmitScalarExpr(OAShE->getBase()), CGF.getContext().getTypeAlignInChars( - OAShE->getBase()->getType())); + OAShE->getBase()->getType(), + false /* NeedsPreferredAlignment */)); } else { LB = CGF.EmitOMPSharedLValue(I->getAssociatedExpression()) .getAddress(CGF); @@ -8652,7 +8657,8 @@ // Copy the value of the original variable to the new global copy. CGF.Builder.CreateMemCpy( CGF.MakeNaturalAlignAddrLValue(Addr, ElementType).getAddress(CGF), - Address(CV, CGF.getContext().getTypeAlignInChars(ElementType)), + Address(CV, CGF.getContext().getTypeAlignInChars( + ElementType, false /* NeedsPreferredAlignment */)), CombinedInfo.Sizes.back(), /*IsVolatile=*/false); // Use new global variable as the base pointers. CombinedInfo.BasePointers.push_back(Addr); @@ -8796,7 +8802,9 @@ Info.BasePointersArray, 0, I); BP = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( BP, BPVal->getType()->getPointerTo(/*AddrSpace=*/0)); - Address BPAddr(BP, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy)); + Address BPAddr( + BP, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy, + false /* NeedsPreferredAlignment */)); CGF.Builder.CreateStore(BPVal, BPAddr); if (Info.requiresDevicePointerInfo()) @@ -8810,7 +8818,8 @@ Info.PointersArray, 0, I); P = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( P, PVal->getType()->getPointerTo(/*AddrSpace=*/0)); - Address PAddr(P, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy)); + Address PAddr(P, Ctx.getTypeAlignInChars( + Ctx.VoidPtrTy, false /* NeedsPreferredAlignment */)); CGF.Builder.CreateStore(PVal, PAddr); if (hasRuntimeEvaluationCaptureSize) { @@ -8819,7 +8828,8 @@ Info.SizesArray, /*Idx0=*/0, /*Idx1=*/I); - Address SAddr(S, Ctx.getTypeAlignInChars(Int64Ty)); + Address SAddr(S, Ctx.getTypeAlignInChars( + Int64Ty, false /* NeedsPreferredAlignment */)); CGF.Builder.CreateStore(CGF.Builder.CreateIntCast(CombinedInfo.Sizes[I], CGM.Int64Ty, /*isSigned=*/true), diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp --- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp @@ -2138,7 +2138,10 @@ // Use actual memory size of the record including the padding // for alignment purposes. unsigned Alignment = - CGM.getContext().getTypeAlignInChars(GlobalRecTy).getQuantity(); + CGM.getContext() + .getTypeAlignInChars(GlobalRecTy, + false /* NeedsPreferredAlignment */) + .getQuantity(); unsigned GlobalRecordSize = CGM.getContext().getTypeSizeInChars(GlobalRecTy).getQuantity(); GlobalRecordSize = llvm::alignTo(GlobalRecordSize, Alignment); @@ -2184,7 +2187,10 @@ // Use actual memory size of the record including the padding // for alignment purposes. unsigned Alignment = - CGM.getContext().getTypeAlignInChars(SecGlobalRecTy).getQuantity(); + CGM.getContext() + .getTypeAlignInChars(SecGlobalRecTy, + false /* NeedsPreferredAlignment */) + .getQuantity(); unsigned GlobalRecordSize = CGM.getContext().getTypeSizeInChars(SecGlobalRecTy).getQuantity(); GlobalRecordSize = llvm::alignTo(GlobalRecordSize, Alignment); @@ -2217,13 +2223,18 @@ for (const RecordDecl *RD : GlobalizedRecords.back().Records) { QualType RDTy = CGM.getContext().getRecordType(RD); unsigned Alignment = - CGM.getContext().getTypeAlignInChars(RDTy).getQuantity(); + CGM.getContext() + .getTypeAlignInChars(RDTy, false /* NeedsPreferredAlignment */) + .getQuantity(); unsigned Size = CGM.getContext().getTypeSizeInChars(RDTy).getQuantity(); Offset = llvm::alignTo(llvm::alignTo(Offset, Alignment) + Size, Alignment); } unsigned Alignment = - CGM.getContext().getTypeAlignInChars(GlobalRecTy).getQuantity(); + CGM.getContext() + .getTypeAlignInChars(GlobalRecTy, + false /* NeedsPreferredAlignment */) + .getQuantity(); Offset = llvm::alignTo(Offset, Alignment); GlobalizedRecords.back().Records.push_back(GlobalizedVarsRecord); ++GlobalizedRecords.back().RegionCounter; @@ -2239,7 +2250,8 @@ /*DestWidth=*/16, /*Signed=*/0); llvm::Value *IsInSharedMemory = CGF.EmitLoadOfScalar( Address(UseSharedMemory, - CGM.getContext().getTypeAlignInChars(Int16Ty)), + CGM.getContext().getTypeAlignInChars( + Int16Ty, false /* NeedsPreferredAlignment */)), /*Volatile=*/false, Int16Ty, Loc); auto *StaticGlobalized = new llvm::GlobalVariable( CGM.getModule(), CGM.Int8Ty, /*isConstant=*/false, @@ -2448,7 +2460,8 @@ /*DestWidth=*/16, /*Signed=*/0); llvm::Value *IsInSharedMemory = CGF.EmitLoadOfScalar( Address(GlobalizedRecords.back().UseSharedMemory, - CGM.getContext().getTypeAlignInChars(Int16Ty)), + CGM.getContext().getTypeAlignInChars( + Int16Ty, false /* NeedsPreferredAlignment */)), /*Volatile=*/false, Int16Ty, GlobalizedRecords.back().Loc); llvm::Value *Args[] = { llvm::ConstantInt::get( @@ -3070,8 +3083,10 @@ Bld.CreateNUWAdd(DestBase.getPointer(), CurrentOffset); ScratchPadElemAbsolutePtrVal = Bld.CreateIntToPtr(ScratchPadElemAbsolutePtrVal, CGF.VoidPtrTy); - DestElementAddr = Address(ScratchPadElemAbsolutePtrVal, - C.getTypeAlignInChars(Private->getType())); + DestElementAddr = + Address(ScratchPadElemAbsolutePtrVal, + C.getTypeAlignInChars(Private->getType(), + false /* NeedsPreferredAlignment */)); IncrScratchpadDest = true; break; } @@ -3085,8 +3100,10 @@ Bld.CreateNUWAdd(SrcBase.getPointer(), CurrentOffset); ScratchPadElemAbsolutePtrVal = Bld.CreateIntToPtr(ScratchPadElemAbsolutePtrVal, CGF.VoidPtrTy); - SrcElementAddr = Address(ScratchPadElemAbsolutePtrVal, - C.getTypeAlignInChars(Private->getType())); + SrcElementAddr = + Address(ScratchPadElemAbsolutePtrVal, + C.getTypeAlignInChars(Private->getType(), + false /* NeedsPreferredAlignment */)); IncrScratchpadSrc = true; // Step 1.2: Create a temporary to store the element in the destination @@ -3280,7 +3297,8 @@ // unsigned RealTySize = C.getTypeSizeInChars(Private->getType()) - .alignTo(C.getTypeAlignInChars(Private->getType())) + .alignTo(C.getTypeAlignInChars(Private->getType(), + false /* NeedsPreferredAlignment */)) .getQuantity(); for (unsigned TySize = 4; TySize > 0 && RealTySize > 0; TySize /=2) { unsigned NumIters = RealTySize / TySize; @@ -3720,8 +3738,9 @@ // elemptr = ((CopyType*)(elemptrptr)) + I ElemPtrPtr = Bld.CreatePointerBitCastOrAddrSpaceCast( ElemPtrPtr, CGF.ConvertTypeForMem(Private->getType())->getPointerTo()); - Address ElemPtr = - Address(ElemPtrPtr, C.getTypeAlignInChars(Private->getType())); + Address ElemPtr = Address( + ElemPtrPtr, C.getTypeAlignInChars(Private->getType(), + false /* NeedsPreferredAlignment */)); const ValueDecl *VD = cast(Private)->getDecl(); // Global = Buffer.VD[Idx]; const FieldDecl *FD = VarFieldMap.lookup(VD); @@ -3924,8 +3943,9 @@ // elemptr = ((CopyType*)(elemptrptr)) + I ElemPtrPtr = Bld.CreatePointerBitCastOrAddrSpaceCast( ElemPtrPtr, CGF.ConvertTypeForMem(Private->getType())->getPointerTo()); - Address ElemPtr = - Address(ElemPtrPtr, C.getTypeAlignInChars(Private->getType())); + Address ElemPtr = Address( + ElemPtrPtr, C.getTypeAlignInChars(Private->getType(), + false /* NeedsPreferredAlignment */)); const ValueDecl *VD = cast(Private)->getDecl(); // Global = Buffer.VD[Idx]; const FieldDecl *FD = VarFieldMap.lookup(VD); @@ -5122,7 +5142,9 @@ unsigned RecAlignment = 0; for (const RecordDecl *RD : Records.Records) { QualType RDTy = C.getRecordType(RD); - unsigned Alignment = C.getTypeAlignInChars(RDTy).getQuantity(); + unsigned Alignment = + C.getTypeAlignInChars(RDTy, false /* NeedsPreferredAlignment */) + .getQuantity(); RecAlignment = std::max(RecAlignment, Alignment); unsigned RecSize = C.getTypeSizeInChars(RDTy).getQuantity(); Size = diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1104,11 +1104,12 @@ MD->getParent()->getLambdaCaptureDefault() == LCD_None) SkippedChecks.set(SanitizerKind::Null, true); - EmitTypeCheck(isa(MD) ? TCK_ConstructorCall - : TCK_MemberCall, - Loc, CXXABIThisValue, ThisTy, - getContext().getTypeAlignInChars(ThisTy->getPointeeType()), - SkippedChecks); + EmitTypeCheck( + isa(MD) ? TCK_ConstructorCall : TCK_MemberCall, + Loc, CXXABIThisValue, ThisTy, + getContext().getTypeAlignInChars(ThisTy->getPointeeType(), + false /* NeedsPreferredAlignment */), + SkippedChecks); } } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4307,7 +4307,8 @@ // alignments for common symbols via the aligncomm directive, so this // restriction only applies to MSVC environments. if (Context.getTargetInfo().getTriple().isKnownWindowsMSVCEnvironment() && - Context.getTypeAlignIfKnown(D->getType()) > + Context.getTypeAlignIfKnown(D->getType(), + false /* NeedsPreferredAlignment */) > Context.toBits(CharUnits::fromQuantity(32))) return true; @@ -4876,8 +4877,11 @@ GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); // Don't enforce the target's minimum global alignment, since the only use // of the string is via this class initializer. - CharUnits Align = isUTF16 ? Context.getTypeAlignInChars(Context.ShortTy) - : Context.getTypeAlignInChars(Context.CharTy); + CharUnits Align = + isUTF16 ? Context.getTypeAlignInChars(Context.ShortTy, + false /* NeedsPreferredAlignment */) + : Context.getTypeAlignInChars( + Context.CharTy, false /* NeedsPreferredAlignment */); GV->setAlignment(Align.getAsAlign()); // FIXME: We set the section explicitly to avoid a bug in ld64 224.1. @@ -5151,7 +5155,8 @@ if (Init == E->getSubExpr()) MaterializedType = E->getType(); - CharUnits Align = getContext().getTypeAlignInChars(MaterializedType); + CharUnits Align = getContext().getTypeAlignInChars( + MaterializedType, false /* NeedsPreferredAlignment */); if (llvm::Constant *Slot = MaterializedGlobalTemporaryMap[E]) return ConstantAddress(Slot, Align); @@ -6069,7 +6074,8 @@ if (forPointeeType && !AlignForArray && (RD = T->getAsCXXRecordDecl())) { Alignment = getClassPointerAlignment(RD); } else { - Alignment = getContext().getTypeAlignInChars(T); + Alignment = getContext().getTypeAlignInChars( + T, false /* NeedsPreferredAlignment */); if (T.getQualifiers().hasUnaligned()) Alignment = CharUnits::One(); } diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -1216,7 +1216,8 @@ // If C++ prohibits us from making a copy, return by address. if (!RD->canPassInRegisters()) { - auto Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType()); + auto Align = CGM.getContext().getTypeAlignInChars( + FI.getReturnType(), false /* NeedsPreferredAlignment */); FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false); return true; } @@ -2111,7 +2112,8 @@ // The array cookie is a size_t; pad that up to the element alignment. // The cookie is actually right-justified in that space. return std::max(CharUnits::fromQuantity(CGM.SizeSizeInBytes), - CGM.getContext().getTypeAlignInChars(elementType)); + CGM.getContext().getTypeAlignInChars( + elementType, true /* NeedsPreferredAlignment */)); } Address ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, @@ -2127,8 +2129,9 @@ CharUnits SizeSize = CGF.getSizeSize(); // The size of the cookie. - CharUnits CookieSize = - std::max(SizeSize, Ctx.getTypeAlignInChars(ElementType)); + CharUnits CookieSize = std::max( + SizeSize, + Ctx.getTypeAlignInChars(ElementType, true /* NeedsPreferredAlignment */)); assert(CookieSize == getArrayCookieSizeImpl(ElementType)); // Compute an offset to the cookie. @@ -2196,7 +2199,8 @@ // 8, so we can dismiss this as typical ABI-author blindness to // actual language complexity and round up to the element alignment. return std::max(CharUnits::fromQuantity(2 * CGM.SizeSizeInBytes), - CGM.getContext().getTypeAlignInChars(elementType)); + CGM.getContext().getTypeAlignInChars( + elementType, false /* NeedsPreferredAlignment */)); } Address ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, @@ -2994,7 +2998,8 @@ // get the mangled name of the type. llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext, Name.substr(4)); - auto Align = CGM.getContext().getTypeAlignInChars(CGM.getContext().CharTy); + auto Align = CGM.getContext().getTypeAlignInChars( + CGM.getContext().CharTy, false /* NeedsPreferredAlignment */); llvm::GlobalVariable *GV = CGM.CreateOrReplaceCXXRuntimeVariable( Name, Init->getType(), Linkage, Align.getQuantity()); diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -1106,7 +1106,8 @@ bool isInstanceMethod = FI.isInstanceMethod(); if (isIndirectReturn || !isSimple || isInstanceMethod) { - CharUnits Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType()); + CharUnits Align = CGM.getContext().getTypeAlignInChars( + FI.getReturnType(), false /* NeedsPreferredAlignment */); FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false); FI.getReturnInfo().setSRetAfterThis(isInstanceMethod); @@ -2092,8 +2093,8 @@ assert(!CGM.getModule().getNamedGlobal(Name) && "vbtable with this name already exists: mangling bug?"); - CharUnits Alignment = - CGM.getContext().getTypeAlignInChars(CGM.getContext().IntTy); + CharUnits Alignment = CGM.getContext().getTypeAlignInChars( + CGM.getContext().IntTy, false /* NeedsPreferredAlignment */); llvm::GlobalVariable *GV = CGM.CreateOrReplaceCXXRuntimeVariable( Name, VBTableType, Linkage, Alignment.getQuantity()); GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); @@ -2254,8 +2255,9 @@ // The array cookie is always a size_t; we then pad that out to the // alignment of the element type. ASTContext &Ctx = getContext(); - return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()), - Ctx.getTypeAlignInChars(type)); + return std::max( + Ctx.getTypeSizeInChars(Ctx.getSizeType()), + Ctx.getTypeAlignInChars(type, false /* NeedsPreferredAlignment */)); } llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, diff --git a/clang/lib/CodeGen/SwiftCallingConv.cpp b/clang/lib/CodeGen/SwiftCallingConv.cpp --- a/clang/lib/CodeGen/SwiftCallingConv.cpp +++ b/clang/lib/CodeGen/SwiftCallingConv.cpp @@ -823,7 +823,8 @@ lowering.addTypedData(type, CharUnits::Zero()); lowering.finish(); - CharUnits alignment = CGM.getContext().getTypeAlignInChars(type); + CharUnits alignment = CGM.getContext().getTypeAlignInChars( + type, false /* NeedsPreferredAlignment */); return classifyExpandedType(lowering, forReturn, alignment); } diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -56,7 +56,8 @@ llvm::LLVMContext &LLVMContext) { // Alignment and Size are measured in bits. const uint64_t Size = Context.getTypeSize(Ty); - const uint64_t Alignment = Context.getTypeAlign(Ty); + const uint64_t Alignment = + Context.getTypeAlign(Ty, false /* NeedsPreferredAlignment */); llvm::Type *IntType = llvm::Type::getIntNTy(LLVMContext, Alignment); const uint64_t NumElements = (Size + Alignment - 1) / Alignment; return ABIArgInfo::getDirect(llvm::ArrayType::get(IntType, NumElements)); @@ -83,14 +84,16 @@ ABIArgInfo ABIInfo::getNaturalAlignIndirect(QualType Ty, bool ByVal, bool Realign, llvm::Type *Padding) const { - return ABIArgInfo::getIndirect(getContext().getTypeAlignInChars(Ty), ByVal, - Realign, Padding); + return ABIArgInfo::getIndirect( + getContext().getTypeAlignInChars(Ty, false /* NeedsPreferredAlignment */), + ByVal, Realign, Padding); } ABIArgInfo ABIInfo::getNaturalAlignIndirectInReg(QualType Ty, bool Realign) const { - return ABIArgInfo::getIndirectInReg(getContext().getTypeAlignInChars(Ty), - /*ByVal*/ false, Realign); + return ABIArgInfo::getIndirectInReg( + getContext().getTypeAlignInChars(Ty, false /* NeedsPreferredAlignment */), + /*ByVal*/ false, Realign); } Address ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, @@ -349,7 +352,8 @@ /// /// \param IsIndirect - Values of this type are passed indirectly. /// \param ValueInfo - The size and alignment of this type, generally -/// computed with getContext().getTypeInfoInChars(ValueTy). +/// computed with getContext().getTypeInfoInChars(ValueTy, +/// NeedsPreferredAlignment). /// \param SlotSizeAndAlign - The size and alignment of a stack slot. /// Each argument will be allocated to a multiple of this number of /// slots, and all the slots will be aligned to this value. @@ -655,7 +659,8 @@ !AI.getIndirectRealign() && "Unexpected IndirectRealign seen in arginfo in generic VAArg emitter!"); - auto TyInfo = CGF.getContext().getTypeInfoInChars(Ty); + auto TyInfo = CGF.getContext().getTypeInfoInChars( + Ty, false /* NeedsPreferredAlignment */); CharUnits TyAlignForABI = TyInfo.second; llvm::Type *BaseTy = @@ -914,10 +919,11 @@ bool IsIndirect = isAggregateTypeForABI(Ty) && !isEmptyRecord(getContext(), Ty, true) && !isSingleElementStruct(Ty, getContext()); - return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, - getContext().getTypeInfoInChars(Ty), - CharUnits::fromQuantity(4), - /*AllowHigherAlign=*/true); + return emitVoidPtrVAArg( + CGF, VAListAddr, Ty, IsIndirect, + getContext().getTypeInfoInChars(Ty, false /* NeedsPreferredAlignment */), + CharUnits::fromQuantity(4), + /*AllowHigherAlign=*/true); } //===----------------------------------------------------------------------===// @@ -1623,7 +1629,8 @@ } // Compute the byval alignment. - unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8; + unsigned TypeAlign = + getContext().getTypeAlign(Ty, false /* NeedsPreferredAlignment */) / 8; unsigned StackAlign = getTypeStackAlignInBytes(Ty, TypeAlign); if (StackAlign == 0) return ABIArgInfo::getIndirect(CharUnits::fromQuantity(4), /*ByVal=*/true); @@ -1763,7 +1770,8 @@ bool IsVectorCall = State.CC == llvm::CallingConv::X86_VectorCall; Ty = useFirstFieldIfTransparentUnion(Ty); - TypeInfo TI = getContext().getTypeInfo(Ty); + TypeInfo TI = + getContext().getTypeInfo(Ty, false /* NeedsPreferredAlignment */); // Check with the C++ ABI first. const RecordType *RT = Ty->getAs(); @@ -2056,7 +2064,8 @@ Address X86_32ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty) const { - auto TypeInfo = getContext().getTypeInfoInChars(Ty); + auto TypeInfo = + getContext().getTypeInfoInChars(Ty, false /* NeedsPreferredAlignment */); // x86-32 changes the alignment of certain arguments on the stack. // @@ -2977,7 +2986,9 @@ // fields, it has class MEMORY. // // Only need to check alignment of array base. - if (OffsetBase % getContext().getTypeAlign(AT->getElementType())) + if (OffsetBase % + getContext().getTypeAlign(AT->getElementType(), + false /* NeedsPreferredAlignment */)) return; // Otherwise implement simplified merge. We could be smarter about @@ -3084,7 +3095,9 @@ return; } // Note, skip this test for bit-fields, see below. - if (!BitField && Offset % getContext().getTypeAlign(i->getType())) { + if (!BitField && + Offset % getContext().getTypeAlign( + i->getType(), false /* NeedsPreferredAlignment */)) { Lo = Memory; postMerge(Size, Lo, Hi); return; @@ -3188,7 +3201,9 @@ // Compute the byval alignment. We specify the alignment of the byval in all // cases so that the mid-level optimizer knows the alignment of the byval. - unsigned Align = std::max(getContext().getTypeAlign(Ty) / 8, 8U); + unsigned Align = std::max( + getContext().getTypeAlign(Ty, false /* NeedsPreferredAlignment */) / 8, + 8U); // Attempt to avoid passing indirect results using byval when possible. This // is important for good codegen. @@ -3923,7 +3938,8 @@ // byte boundary if alignment needed by type exceeds 8 byte boundary. // It isn't stated explicitly in the standard, but in practice we use // alignment greater than 16 where necessary. - CharUnits Align = CGF.getContext().getTypeAlignInChars(Ty); + CharUnits Align = CGF.getContext().getTypeAlignInChars( + Ty, false /* NeedsPreferredAlignment */); if (Align > CharUnits::fromQuantity(8)) { overflow_arg_area = emitRoundPointerUpToAlignment(CGF, overflow_arg_area, Align); @@ -4063,8 +4079,8 @@ RegAddr = CGF.Builder.CreateElementBitCast(RegAddr, LTy); // Copy to a temporary if necessary to ensure the appropriate alignment. - std::pair SizeAlign = - getContext().getTypeInfoInChars(Ty); + std::pair SizeAlign = getContext().getTypeInfoInChars( + Ty, false /* NeedsPreferredAlignment */); uint64_t TySize = SizeAlign.first.getQuantity(); CharUnits TyAlign = SizeAlign.second; @@ -4140,7 +4156,8 @@ Address X86_64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty) const { return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false, - CGF.getContext().getTypeInfoInChars(Ty), + CGF.getContext().getTypeInfoInChars( + Ty, false /* NeedsPreferredAlignment */), CharUnits::fromQuantity(8), /*allowHigherAlign*/ false); } @@ -4170,7 +4187,8 @@ if (const EnumType *EnumTy = Ty->getAs()) Ty = EnumTy->getDecl()->getIntegerType(); - TypeInfo Info = getContext().getTypeInfo(Ty); + TypeInfo Info = + getContext().getTypeInfo(Ty, false /* NeedsPreferredAlignment */); uint64_t Width = Info.Width; CharUnits Align = getContext().toCharUnitsFromBits(Info.Align); @@ -4362,7 +4380,8 @@ } return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, - CGF.getContext().getTypeInfoInChars(Ty), + CGF.getContext().getTypeInfoInChars( + Ty, false /* NeedsPreferredAlignment */), CharUnits::fromQuantity(8), /*allowHigherAlign*/ false); } @@ -4512,8 +4531,6 @@ if (RetTy->isVoidType()) return ABIArgInfo::getIgnore(); - // TODO: Evaluate if AIX power alignment rule would have an impact on the - // alignment here. if (isAggregateTypeForABI(RetTy)) return getNaturalAlignIndirect(RetTy); @@ -4530,8 +4547,6 @@ if (Ty->isVectorType()) llvm::report_fatal_error("vector type is not supported on AIX yet"); - // TODO: Evaluate if AIX power alignment rule would have an impact on the - // alignment here. if (isAggregateTypeForABI(Ty)) { // Records with non-trivial destructors/copy-constructors should not be // passed by value. @@ -4539,7 +4554,8 @@ return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); CharUnits CCAlign = getParamTypeAlignment(Ty); - CharUnits TyAlign = getContext().getTypeAlignInChars(Ty); + CharUnits TyAlign = getContext().getTypeAlignInChars( + Ty, false /* NeedsPreferredAlignment */); return ABIArgInfo::getIndirect(CCAlign, /*ByVal*/ true, /*Realign*/ TyAlign > CCAlign); @@ -4571,7 +4587,8 @@ if (Ty->isVectorType()) llvm::report_fatal_error("vector type is not supported on AIX yet"); - auto TypeInfo = getContext().getTypeInfoInChars(Ty); + auto TypeInfo = + getContext().getTypeInfoInChars(Ty, false /* NeedsPreferredAlignment */); TypeInfo.second = getParamTypeAlignment(Ty); CharUnits SlotSize = CharUnits::fromQuantity(PtrByteSize); @@ -4690,7 +4707,8 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, QualType Ty) const { if (getTarget().getTriple().isOSDarwin()) { - auto TI = getContext().getTypeInfoInChars(Ty); + auto TI = getContext().getTypeInfoInChars( + Ty, false /* NeedsPreferredAlignment */); TI.second = getParamTypeAlignment(Ty); CharUnits SlotSize = CharUnits::fromQuantity(4); @@ -4800,7 +4818,8 @@ CharUnits Size; if (!isIndirect) { - auto TypeInfo = CGF.getContext().getTypeInfoInChars(Ty); + auto TypeInfo = CGF.getContext().getTypeInfoInChars( + Ty, false /* NeedsPreferredAlignment */); Size = TypeInfo.first.alignTo(OverflowAreaAlign); } else { Size = CGF.getPointerSize(); @@ -4810,7 +4829,8 @@ Address OverflowArea(Builder.CreateLoad(OverflowAreaAddr, "argp.cur"), OverflowAreaAlign); // Round up address of argument to alignment - CharUnits Align = CGF.getContext().getTypeAlignInChars(Ty); + CharUnits Align = CGF.getContext().getTypeAlignInChars( + Ty, false /* NeedsPreferredAlignment */); if (Align > OverflowAreaAlign) { llvm::Value *Ptr = OverflowArea.getPointer(); OverflowArea = Address(emitRoundPointerUpToAlignment(CGF, Ptr, Align), @@ -4834,7 +4854,8 @@ // Load the pointer if the argument was passed indirectly. if (isIndirect) { Result = Address(Builder.CreateLoad(Result, "aggr"), - getContext().getTypeAlignInChars(Ty)); + getContext().getTypeAlignInChars( + Ty, false /* NeedsPreferredAlignment */)); } return Result; @@ -5080,8 +5101,11 @@ // Otherwise, we only need alignment for any aggregate type that // has an alignment requirement of >= 16 bytes. - if (isAggregateTypeForABI(Ty) && getContext().getTypeAlign(Ty) >= 128) { - if (HasQPX && getContext().getTypeAlign(Ty) >= 256) + if (isAggregateTypeForABI(Ty) && + getContext().getTypeAlign(Ty, false /* NeedsPreferredAlignment */) >= + 128) { + if (HasQPX && getContext().getTypeAlign( + Ty, false /* NeedsPreferredAlignment */) >= 256) return CharUnits::fromQuantity(32); return CharUnits::fromQuantity(16); } @@ -5254,7 +5278,10 @@ return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); uint64_t ABIAlign = getParamTypeAlignment(Ty).getQuantity(); - uint64_t TyAlign = getContext().getTypeAlignInChars(Ty).getQuantity(); + uint64_t TyAlign = + getContext() + .getTypeAlignInChars(Ty, false /* NeedsPreferredAlignment */) + .getQuantity(); // ELFv2 homogeneous aggregates are passed as array types. const Type *Base = nullptr; @@ -5363,7 +5390,8 @@ // Based on ARMABIInfo::EmitVAArg, adjusted for 64-bit machine. Address PPC64_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty) const { - auto TypeInfo = getContext().getTypeInfoInChars(Ty); + auto TypeInfo = + getContext().getTypeInfoInChars(Ty, false /* NeedsPreferredAlignment */); TypeInfo.second = getParamTypeAlignment(Ty); CharUnits SlotSize = CharUnits::fromQuantity(8); @@ -5669,8 +5697,9 @@ Alignment = getContext().getTypeUnadjustedAlign(Ty); Alignment = Alignment < 128 ? 64 : 128; } else { - Alignment = std::max(getContext().getTypeAlign(Ty), - (unsigned)getTarget().getPointerWidth(0)); + Alignment = std::max( + getContext().getTypeAlign(Ty, false /* NeedsPreferredAlignment */), + (unsigned)getTarget().getPointerWidth(0)); } Size = llvm::alignTo(Size, Alignment); @@ -5727,7 +5756,8 @@ if (getTarget().isRenderScriptTarget()) { return coerceToIntArray(RetTy, getContext(), getVMContext()); } - unsigned Alignment = getContext().getTypeAlign(RetTy); + unsigned Alignment = + getContext().getTypeAlign(RetTy, false /* NeedsPreferredAlignment */); Size = llvm::alignTo(Size, 64); // round up to multiple of 8 bytes // We use a pair of i64 for 16-byte aggregate with 8-byte alignment. @@ -5933,7 +5963,8 @@ // qN+1, ...). We reload and store into a temporary local variable // contiguously. assert(!IsIndirect && "Homogeneous aggregates should be passed directly"); - auto BaseTyInfo = getContext().getTypeInfoInChars(QualType(Base, 0)); + auto BaseTyInfo = getContext().getTypeInfoInChars( + QualType(Base, 0), false /* NeedsPreferredAlignment */); llvm::Type *BaseTy = CGF.ConvertType(QualType(Base, 0)); llvm::Type *HFATy = llvm::ArrayType::get(BaseTy, NumMembers); Address Tmp = CGF.CreateTempAlloca(HFATy, @@ -6062,7 +6093,8 @@ // The size of the actual thing passed, which might end up just // being a pointer for indirect types. - auto TyInfo = getContext().getTypeInfoInChars(Ty); + auto TyInfo = + getContext().getTypeInfoInChars(Ty, false /* NeedsPreferredAlignment */); // Arguments bigger than 16 bytes which aren't homogeneous // aggregates should be passed indirectly. @@ -6080,7 +6112,8 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty) const { return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false, - CGF.getContext().getTypeInfoInChars(Ty), + CGF.getContext().getTypeInfoInChars( + Ty, false /* NeedsPreferredAlignment */), CharUnits::fromQuantity(8), /*allowHigherAlign*/ false); } @@ -6432,7 +6465,10 @@ // bigger than 128-bits, they get placed in space allocated by the caller, // and a pointer is passed. return ABIArgInfo::getIndirect( - CharUnits::fromQuantity(getContext().getTypeAlign(Ty) / 8), false); + CharUnits::fromQuantity( + getContext().getTypeAlign(Ty, false /* NeedsPreferredAlignment */) / + 8), + false); } // Support byval for ARM. @@ -6446,7 +6482,9 @@ TyAlign = getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity(); ABIAlign = std::min(std::max(TyAlign, (uint64_t)4), (uint64_t)8); } else { - TyAlign = getContext().getTypeAlignInChars(Ty).getQuantity(); + TyAlign = getContext() + .getTypeAlignInChars(Ty, false /* NeedsPreferredAlignment */) + .getQuantity(); } if (getContext().getTypeSizeInChars(Ty) > CharUnits::fromQuantity(64)) { assert(getABIKind() != ARMABIInfo::AAPCS16_VFP && "unexpected byval"); @@ -6958,7 +6996,8 @@ unsigned MaxSize) const { // Alignment and Size are measured in bits. const uint64_t Size = getContext().getTypeSize(Ty); - const uint64_t Alignment = getContext().getTypeAlign(Ty); + const uint64_t Alignment = + getContext().getTypeAlign(Ty, false /* NeedsPreferredAlignment */); const unsigned Div = std::min(MaxSize, Alignment); llvm::Type *IntType = llvm::Type::getIntNTy(getVMContext(), Div); const uint64_t NumElements = (Size + Div - 1) / Div; @@ -7286,7 +7325,8 @@ // in either GPRs or FPRs. Vector arguments occupy 8 or 16 bytes and are // always passed on the stack. Ty = getContext().getCanonicalType(Ty); - auto TyInfo = getContext().getTypeInfoInChars(Ty); + auto TyInfo = + getContext().getTypeInfoInChars(Ty, false /* NeedsPreferredAlignment */); llvm::Type *ArgTy = CGF.ConvertTypeForMem(Ty); llvm::Type *DirectTy = ArgTy; ABIArgInfo AI = classifyArgumentType(Ty); @@ -7747,7 +7787,8 @@ uint64_t OrigOffset = Offset; uint64_t TySize = getContext().getTypeSize(Ty); - uint64_t Align = getContext().getTypeAlign(Ty) / 8; + uint64_t Align = + getContext().getTypeAlign(Ty, false /* NeedsPreferredAlignment */) / 8; Align = std::min(std::max(Align, (uint64_t)MinABIStackAlignInBytes), (uint64_t)StackAlignInBytes); @@ -7915,7 +7956,8 @@ Ty->isSignedIntegerType()); } - auto TyInfo = getContext().getTypeInfoInChars(Ty); + auto TyInfo = + getContext().getTypeInfoInChars(Ty, false /* NeedsPreferredAlignment */); // The alignment of things in the argument area is never larger than // StackAlignInBytes. @@ -8185,7 +8227,8 @@ return ABIArgInfo::getIgnore(); uint64_t Size = getContext().getTypeSize(Ty); - unsigned Align = getContext().getTypeAlign(Ty); + unsigned Align = + getContext().getTypeAlign(Ty, false /* NeedsPreferredAlignment */); if (Size > 64) return getNaturalAlignIndirect(Ty, /*ByVal=*/true); @@ -8256,7 +8299,9 @@ llvm::Value *__overflow_area_pointer = CGF.Builder.CreateLoad( __overflow_area_pointer_p, "__overflow_area_pointer"); - uint64_t Align = CGF.getContext().getTypeAlign(Ty) / 8; + uint64_t Align = + CGF.getContext().getTypeAlign(Ty, false /* NeedsPreferredAlignment */) / + 8; if (Align > 4) { // Alignment should be a power of 2. assert((Align & (Align - 1)) == 0 && "Alignment is not power of 2!"); @@ -8306,7 +8351,9 @@ Address VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap"); llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); // Handle address alignment for type alignment > 32 bits - uint64_t TyAlign = CGF.getContext().getTypeAlign(Ty) / 8; + uint64_t TyAlign = + CGF.getContext().getTypeAlign(Ty, false /* NeedsPreferredAlignment */) / + 8; if (TyAlign > 4) { assert((TyAlign & (TyAlign - 1)) == 0 && "Alignment is not power of 2!"); llvm::Value *AddrAsInt = Builder.CreatePtrToInt(Addr, CGF.Int32Ty); @@ -8546,7 +8593,8 @@ // Compute the byval alignment. const unsigned MinABIStackAlignInBytes = 4; - unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8; + unsigned TypeAlign = + getContext().getTypeAlign(Ty, false /* NeedsPreferredAlignment */) / 8; return ABIArgInfo::getIndirect(CharUnits::fromQuantity(4), /*ByVal=*/true, /*Realign=*/TypeAlign > MinABIStackAlignInBytes); @@ -8816,7 +8864,8 @@ if (!getContext().getLangOpts().OpenCL && LTy == OrigLTy && isAggregateTypeForABI(Ty)) { return ABIArgInfo::getIndirectAliased( - getContext().getTypeAlignInChars(Ty), + getContext().getTypeAlignInChars(Ty, + false /* NeedsPreferredAlignment */), getContext().getTargetAddressSpace(LangAS::opencl_constant), false /*Realign*/, nullptr /*Padding*/); } @@ -9371,7 +9420,8 @@ Address Addr(Builder.CreateLoad(VAListAddr, "ap.cur"), SlotSize); llvm::Type *ArgPtrTy = llvm::PointerType::getUnqual(ArgTy); - auto TypeInfo = getContext().getTypeInfoInChars(Ty); + auto TypeInfo = + getContext().getTypeInfoInChars(Ty, false /* NeedsPreferredAlignment */); Address ArgAddr = Address::invalid(); CharUnits Stride; @@ -9529,16 +9579,18 @@ ABIArgInfo ARCABIInfo::getIndirectByValue(QualType Ty) const { // Compute the byval alignment. const unsigned MinABIStackAlignInBytes = 4; - unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8; + unsigned TypeAlign = + getContext().getTypeAlign(Ty, false /* NeedsPreferredAlignment */) / 8; return ABIArgInfo::getIndirect(CharUnits::fromQuantity(4), /*ByVal=*/true, TypeAlign > MinABIStackAlignInBytes); } Address ARCABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty) const { - return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false, - getContext().getTypeInfoInChars(Ty), - CharUnits::fromQuantity(4), true); + return emitVoidPtrVAArg( + CGF, VAListAddr, Ty, /*indirect*/ false, + getContext().getTypeInfoInChars(Ty, false /* NeedsPreferredAlignment */), + CharUnits::fromQuantity(4), true); } ABIArgInfo ARCABIInfo::classifyArgumentType(QualType Ty, @@ -9737,7 +9789,8 @@ // Handle the argument. ABIArgInfo AI = classifyArgumentType(Ty); - CharUnits TypeAlign = getContext().getTypeAlignInChars(Ty); + CharUnits TypeAlign = + getContext().getTypeAlignInChars(Ty, false /* NeedsPreferredAlignment */); llvm::Type *ArgTy = CGT.ConvertType(Ty); if (AI.canHaveCoerceToType() && !AI.getCoerceToType()) AI.setCoerceToType(ArgTy); @@ -10614,7 +10667,8 @@ } } - uint64_t NeededAlign = getContext().getTypeAlign(Ty); + uint64_t NeededAlign = + getContext().getTypeAlign(Ty, false /* NeedsPreferredAlignment */); bool MustUseStack = false; // Determine the number of GPRs needed to pass the current argument // according to the ABI. 2*XLen-aligned varargs are passed in "aligned" @@ -10658,7 +10712,8 @@ // Aggregates which are <= 2*XLen will be passed in registers if possible, // so coerce to integers. if (Size <= 2 * XLen) { - unsigned Alignment = getContext().getTypeAlign(Ty); + unsigned Alignment = + getContext().getTypeAlign(Ty, false /* NeedsPreferredAlignment */); // Use a single XLen int if possible, 2*XLen if 2*XLen alignment is // required, and a 2-element XLen array if only XLen alignment is required. @@ -10701,7 +10756,7 @@ } std::pair SizeAndAlign = - getContext().getTypeInfoInChars(Ty); + getContext().getTypeInfoInChars(Ty, false /* NeedsPreferredAlignment */); // Arguments bigger than 2*Xlen bytes are passed indirectly. bool IsIndirect = SizeAndAlign.first > 2 * SlotSize; diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp --- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -6831,7 +6831,8 @@ // FIXME. this alignment represents the host alignment and need be changed to // represent the target alignment. - unsigned Align = Context->getTypeAlign(IVQT)/8; + unsigned Align = + Context->getTypeAlign(IVQT, false /* NeedsPreferredAlignment */) / 8; Align = llvm::Log2_32(Align); Result += llvm::utostr(Align); Result += ", "; CharUnits Size = Context->getTypeSizeInChars(IVQT); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -10220,7 +10220,7 @@ return IntRange(NumPositive, true/*NonNegative*/); else return IntRange(std::max(NumPositive + 1, NumNegative), - false/*NonNegative*/); + false /*NonNegative*/); } if (const auto *EIT = dyn_cast(T)) @@ -13830,7 +13830,8 @@ return P->first.alignmentAtOffset(P->second); // If that failed, return the type's alignment. - return S.Context.getTypeAlignInChars(E->getType()->getPointeeType()); + return S.Context.getTypeAlignInChars(E->getType()->getPointeeType(), + false /* NeedsPreferredAlignment */); } /// CheckCastAlign - Implements -Wcast-align, which warns when a @@ -13852,7 +13853,8 @@ // If the destination has alignment 1, we're done. QualType DestPointee = DestPtr->getPointeeType(); if (DestPointee->isIncompleteType()) return; - CharUnits DestAlign = Context.getTypeAlignInChars(DestPointee); + CharUnits DestAlign = Context.getTypeAlignInChars( + DestPointee, false /* NeedsPreferredAlignment */); if (DestAlign.isOne()) return; // Require that the source be a pointer type. @@ -15350,9 +15352,11 @@ auto MA = llvm::find(MisalignedMembers, MisalignedMember(Op)); if (MA != MisalignedMembers.end() && (T->isIntegerType() || - (T->isPointerType() && (T->getPointeeType()->isIncompleteType() || - Context.getTypeAlignInChars( - T->getPointeeType()) <= MA->Alignment)))) + (T->isPointerType() && + (T->getPointeeType()->isIncompleteType() || + Context.getTypeAlignInChars(T->getPointeeType(), + false /* NeedsPreferredAlignment */) <= + MA->Alignment)))) MisalignedMembers.erase(MA); } } @@ -15413,7 +15417,8 @@ return; // Alignment expected by the whole expression. - CharUnits ExpectedAlignment = Context.getTypeAlignInChars(E->getType()); + CharUnits ExpectedAlignment = Context.getTypeAlignInChars( + E->getType(), false /* NeedsPreferredAlignment */); // No need to do anything else with this case. if (ExpectedAlignment.isOne()) @@ -15428,7 +15433,8 @@ // Compute the CompleteObjectAlignment as the alignment of the whole chain. CharUnits CompleteObjectAlignment = Context.getTypeAlignInChars( - ReverseMemberChain.back()->getParent()->getTypeForDecl()); + ReverseMemberChain.back()->getParent()->getTypeForDecl(), + false /* NeedsPreferredAlignment */); // The base expression of the innermost MemberExpr may give // stronger guarantees than the class containing the member. @@ -15459,8 +15465,10 @@ FDI->getParent()->hasAttr()) { FD = FDI; Alignment = std::min( - Context.getTypeAlignInChars(FD->getType()), - Context.getTypeAlignInChars(FD->getParent()->getTypeForDecl())); + Context.getTypeAlignInChars(FD->getType(), + false /* NeedsPreferredAlignment */), + Context.getTypeAlignInChars(FD->getParent()->getTypeForDecl(), + false /* NeedsPreferredAlignment */)); break; } } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2516,9 +2516,11 @@ Ty = S.Context.getTagDeclType(cast(New)); if (OldAlign == 0) - OldAlign = S.Context.getTypeAlign(Ty); + OldAlign = + S.Context.getTypeAlign(Ty, false /* NeedsPreferredAlignment */); if (NewAlign == 0) - NewAlign = S.Context.getTypeAlign(Ty); + NewAlign = + S.Context.getTypeAlign(Ty, false /* NeedsPreferredAlignment */); } if (OldAlign != NewAlign) { diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1356,10 +1356,11 @@ if (auto *TD = dyn_cast(D)) TD->addAttr(::new (S.Context) PackedAttr(S.Context, AL)); else if (auto *FD = dyn_cast(D)) { - bool BitfieldByteAligned = (!FD->getType()->isDependentType() && - !FD->getType()->isIncompleteType() && - FD->isBitField() && - S.Context.getTypeAlign(FD->getType()) <= 8); + bool BitfieldByteAligned = + (!FD->getType()->isDependentType() && + !FD->getType()->isIncompleteType() && FD->isBitField() && + S.Context.getTypeAlign(FD->getType(), + false /* NeedsPreferredAlignment */) <= 8); if (S.getASTContext().getTargetInfo().getTriple().isPS4()) { if (BitfieldByteAligned) @@ -3643,7 +3644,8 @@ if (FirstType->isIncompleteType()) return; uint64_t FirstSize = S.Context.getTypeSize(FirstType); - uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); + uint64_t FirstAlign = + S.Context.getTypeAlign(FirstType, false /* NeedsPreferredAlignment */); for (; Field != FieldEnd; ++Field) { QualType FieldType = Field->getType(); if (FieldType->isIncompleteType()) @@ -3654,11 +3656,14 @@ // sufficient (consider structs passed on the stack instead of in registers // as an example). if (S.Context.getTypeSize(FieldType) != FirstSize || - S.Context.getTypeAlign(FieldType) > FirstAlign) { + S.Context.getTypeAlign(FieldType, false /* NeedsPreferredAlignment */) > + FirstAlign) { // Warn if we drop the attribute. bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; - unsigned FieldBits = isSize ? S.Context.getTypeSize(FieldType) - : S.Context.getTypeAlign(FieldType); + unsigned FieldBits = + isSize ? S.Context.getTypeSize(FieldType) + : S.Context.getTypeAlign(FieldType, + false /* NeedsPreferredAlignment */); S.Diag(Field->getLocation(), diag::warn_transparent_union_attribute_field_size_align) << isSize << *Field << FieldBits; @@ -3916,7 +3921,8 @@ << LastAlignedAttr << DiagTy; } else if (AlignasAttr && Align) { CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align); - CharUnits NaturalAlign = Context.getTypeAlignInChars(UnderlyingTy); + CharUnits NaturalAlign = Context.getTypeAlignInChars( + UnderlyingTy, false /* NeedsPreferredAlignment */); if (NaturalAlign > RequestedAlign) Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned) << DiagTy << (unsigned)NaturalAlign.getQuantity(); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -3155,8 +3155,10 @@ // validate the basic, low-level compatibility of the two types. // As a minimum, require the sizes and alignments to match. - TypeInfo LeftTI = Context.getTypeInfo(left); - TypeInfo RightTI = Context.getTypeInfo(right); + TypeInfo LeftTI = + Context.getTypeInfo(left, false /* NeedsPreferredAlignment */); + TypeInfo RightTI = + Context.getTypeInfo(right, false /* NeedsPreferredAlignment */); if (LeftTI.Width != RightTI.Width) return false; @@ -3212,8 +3214,10 @@ return false; // Require size and alignment to match. - TypeInfo LeftTI = Context.getTypeInfo(lt); - TypeInfo RightTI = Context.getTypeInfo(rt); + TypeInfo LeftTI = + Context.getTypeInfo(lt, false /* NeedsPreferredAlignment */); + TypeInfo RightTI = + Context.getTypeInfo(rt, false /* NeedsPreferredAlignment */); if (LeftTI.Width != RightTI.Width) return false; @@ -3674,7 +3678,7 @@ return true; if (S.LookupMethodInObjectType(Sel, ObjectType, true/*Instance method*/)) return true; - return S.LookupMethodInObjectType(Sel, ObjectType, false/*Class method*/) != + return S.LookupMethodInObjectType(Sel, ObjectType, false /*Class method*/) != nullptr; } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3765,7 +3765,8 @@ bool isSigned = !Literal.isUnsigned; unsigned scale = Context.getFixedPointScale(Ty); - unsigned bit_width = Context.getTypeInfo(Ty).Width; + unsigned bit_width = + Context.getTypeInfo(Ty, false /* NeedsPreferredAlignment */).Width; llvm::APInt Val(bit_width, 0, isSigned); bool Overflowed = Literal.GetFixedPointValue(Val, scale); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1029,7 +1029,8 @@ // alignment. Warn if the exception type requires alignment beyond the minimum // guaranteed by the target C++ runtime. if (Context.getTargetInfo().getCXXABI().isItaniumFamily()) { - CharUnits TypeAlign = Context.getTypeAlignInChars(Ty); + CharUnits TypeAlign = + Context.getTypeAlignInChars(Ty, false /* NeedsPreferredAlignment */); CharUnits ExnObjAlign = Context.getExnObjectAlignment(); if (ExnObjAlign < TypeAlign) { Diag(ThrowLoc, diag::warn_throw_underaligned_obj); @@ -1631,7 +1632,8 @@ /// not known. static bool hasNewExtendedAlignment(Sema &S, QualType AllocType) { return S.getLangOpts().AlignedAllocation && - S.getASTContext().getTypeAlignIfKnown(AllocType) > + S.getASTContext().getTypeAlignIfKnown( + AllocType, false /* NeedsPreferredAlignment */) > S.getASTContext().getTargetInfo().getNewAlign(); } @@ -2115,7 +2117,10 @@ FunctionDecl *OperatorNew = nullptr; FunctionDecl *OperatorDelete = nullptr; unsigned Alignment = - AllocType->isDependentType() ? 0 : Context.getTypeAlign(AllocType); + AllocType->isDependentType() + ? 0 + : Context.getTypeAlign(AllocType, + false /* NeedsPreferredAlignment */); unsigned NewAlignment = Context.getTargetInfo().getNewAlign(); bool PassAlignment = getLangOpts().AlignedAllocation && Alignment > NewAlignment; diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -2123,7 +2123,9 @@ if (!IsByRef && (Ctx.getTypeSizeInChars(Ty) > Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || - Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { + Ctx.getDeclAlign(D) > + Ctx.getTypeAlignInChars(Ctx.getUIntPtrType(), + false /* NeedsPreferredAlignment */))) { IsByRef = true; } diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -3053,7 +3053,9 @@ // Variables with higher required alignment than their type's ABI // alignment cannot use NRVO. if (!VD->getType()->isDependentType() && VD->hasAttr() && - Context.getDeclAlign(VD) > Context.getTypeAlignInChars(VD->getType())) + Context.getDeclAlign(VD) > + Context.getTypeAlignInChars(VD->getType(), + false /* NeedsPreferredAlignment */)) return false; return true; diff --git a/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp --- a/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp @@ -88,8 +88,11 @@ return true; // Warn when there is widening cast. - unsigned ToWidth = Ctx.getTypeInfo(ToPointeeTy).Width; - unsigned OrigWidth = Ctx.getTypeInfo(OrigPointeeTy).Width; + unsigned ToWidth = + Ctx.getTypeInfo(ToPointeeTy, false /* NeedsPreferredAlignment */).Width; + unsigned OrigWidth = + Ctx.getTypeInfo(OrigPointeeTy, false /* NeedsPreferredAlignment */) + .Width; if (ToWidth <= OrigWidth) return true; diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp --- a/clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp @@ -166,7 +166,8 @@ unsigned PlacementNewChecker::getStorageAlign(CheckerContext &C, const ValueDecl *VD) const { - unsigned StorageTAlign = C.getASTContext().getTypeAlign(VD->getType()); + unsigned StorageTAlign = C.getASTContext().getTypeAlign( + VD->getType(), false /* NeedsPreferredAlignment */); if (unsigned SpecifiedAlignment = VD->getMaxAlignment()) StorageTAlign = SpecifiedAlignment; @@ -276,8 +277,10 @@ const Expr *Place = NE->getPlacementArg(0); QualType AllocatedT = NE->getAllocatedType(); - unsigned AllocatedTAlign = C.getASTContext().getTypeAlign(AllocatedT) / - C.getASTContext().getCharWidth(); + unsigned AllocatedTAlign = + C.getASTContext().getTypeAlign(AllocatedT, + false /* NeedsPreferredAlignment */) / + C.getASTContext().getCharWidth(); SVal PlaceVal = C.getSVal(Place); if (const MemRegion *MRegion = PlaceVal.getAsRegion()) { diff --git a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp --- a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp @@ -248,8 +248,8 @@ FieldInfo RetVal; RetVal.Field = FD; auto &Ctx = FD->getASTContext(); - std::tie(RetVal.Size, RetVal.Align) = - Ctx.getTypeInfoInChars(FD->getType()); + std::tie(RetVal.Size, RetVal.Align) = Ctx.getTypeInfoInChars( + FD->getType(), true /* NeedsPreferredAlignment */); assert(llvm::isPowerOf2_64(RetVal.Align.getQuantity())); if (auto Max = FD->getMaxAlignment()) RetVal.Align = std::max(Ctx.toCharUnitsFromBits(Max), RetVal.Align); diff --git a/clang/test/CodeGen/aix-alignment.c b/clang/test/CodeGen/aix-alignment.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/aix-alignment.c @@ -0,0 +1,41 @@ +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -triple powerpc-unknown-aix -emit-llvm -o - %s | \ +// RUN: FileCheck %s --check-prefixes=AIX,AIX32 +// RUN: %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm -o - %s | \ +// RUN: FileCheck %s --check-prefixes=AIX,AIX64 + +// AIX: @d = global double 0.000000e+00, align 8 +double d; + +typedef struct { + double d; + int i; +} StructDouble; + +// AIX: @d1 = global %struct.StructDouble zeroinitializer, align 8 +StructDouble d1; + +// AIX: double @retDouble(double %x) +// AIX: %x.addr = alloca double, align 8 +// AIX: store double %x, double* %x.addr, align 8 +// AIX: load double, double* %x.addr, align 8 +// AIX: ret double %0 +double retDouble(double x) { return x; } + +// AIX32: define void @bar(%struct.StructDouble* noalias sret align 4 %agg.result, %struct.StructDouble* byval(%struct.StructDouble) align 4 %x) +// AIX64: define void @bar(%struct.StructDouble* noalias sret align 4 %agg.result, %struct.StructDouble* byval(%struct.StructDouble) align 8 %x) +// AIX: %0 = bitcast %struct.StructDouble* %agg.result to i8* +// AIX: %1 = bitcast %struct.StructDouble* %x to i8* +// AIX32: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %0, i8* align 4 %1, i32 16, i1 false) +// AIX64: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 8 %1, i64 16, i1 false) +StructDouble bar(StructDouble x) { return x; } + +// AIX: define void @foo(double* %out, double* %in) +// AIX32: %0 = load double*, double** %in.addr, align 4 +// AIX64: %0 = load double*, double** %in.addr, align 8 +// AIX: %1 = load double, double* %0, align 4 +// AIX: %mul = fmul double %1, 2.000000e+00 +// AIX32: %2 = load double*, double** %out.addr, align 4 +// AIX64: %2 = load double*, double** %out.addr, align 8 +// AIX: store double %mul, double* %2, align 4 +void foo(double *out, double *in) { *out = *in * 2; } diff --git a/clang/test/CodeGenCXX/aix-alignment.cpp b/clang/test/CodeGenCXX/aix-alignment.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenCXX/aix-alignment.cpp @@ -0,0 +1,30 @@ +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -triple powerpc-unknown-aix \ +// RUN: -emit-llvm -o - -x c++ %s | \ +// RUN: FileCheck %s --check-prefixes=AIX,AIX32 +// RUN: %clang_cc1 -triple powerpc64-unknown-aix \ +// RUN: -emit-llvm -o - %s -x c++| \ +// RUN: FileCheck %s --check-prefixes=AIX,AIX64 + +struct B { + double d; + ~B() {} +}; + +// AIX32: %call = call noalias nonnull i8* @_Znam(i32 8) +// AIX64: %call = call noalias nonnull i8* @_Znam(i64 8) +B *allocBp() { return new B[0]; } + +typedef struct D { + double d; + int i; + + ~D(){}; +} D; + +// AIX: define void @_Z3foo1D(%struct.D* noalias sret align 4 %agg.result, %struct.D* %x) +// AIX: %1 = bitcast %struct.D* %agg.result to i8* +// AIX: %2 = bitcast %struct.D* %x to i8* +// AIX32 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %1, i8* align 4 %2, i32 16, i1 false) +// AIX64: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %1, i8* align 4 %2, i64 16, i1 false) +D foo(D x) { return x; } diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp --- a/clang/tools/libclang/CXType.cpp +++ b/clang/tools/libclang/CXType.cpp @@ -914,7 +914,8 @@ // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1 // if (QT->isVoidType()) return 1; - return Ctx.getTypeAlignInChars(QT).getQuantity(); + return Ctx.getTypeAlignInChars(QT, false /* NeedsPreferredAlignment */) + .getQuantity(); } CXType clang_Type_getClassType(CXType CT) {