Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -1600,8 +1600,25 @@ if (BaseT.getQualifiers().hasUnaligned()) Align = Target->getCharWidth(); if (const auto *VD = dyn_cast(D)) { - if (VD->hasGlobalStorage() && !ForAlignof) + if (VD->hasGlobalStorage() && !ForAlignof) { Align = std::max(Align, getTargetInfo().getMinGlobalAlign()); + + // MSVC does size based alignment for arm64 based on alignment section + // in below document, replicate that to keep alignment consistent with + // object files compiled by MSVC. + // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions + if (getTargetInfo().getTriple().getArch() == llvm::Triple::aarch64 && + getTargetInfo().getTriple().getEnvironment() == llvm::Triple::MSVC) { + uint64_t TypeSize = getTypeSize(T.getTypePtr()); + if (TypeSize >= 512) { // TypeSize >= 64 bytes + Align = std::max(Align, 128u); // align type at least 16 bytes + } else if (TypeSize >= 64) { // TypeSize >= 8 bytes + Align = std::max(Align, 64u); // align type at least 8 butes + } else if (TypeSize >= 16) { // TypeSize >= 2 bytes + Align = std::max(Align, 32u); // align type at least 4 bytes + } + } + } } }