TomTan created this revision.
TomTan added a reviewer: efriedma.
Herald added subscribers: cfe-commits, kristof.beyls, javed.absar.
Herald added a project: clang.

According to alignment section in below ARM64 ABI document, MSVC could increase 
alignment of global data based on its total size. Clang doesn't do this. 
Compile the same symbol into different alignments by Clang and MSVC could cause 
link error because some instruction encodings, like 64-bit LDR/STR with 
immediate, require the target to be 8 bytes aligned, and linker could choose 
code stream with such LDR/STR instruction from MSVC and 4 bytes aligned data 
from Clang into final image, which actually cannot be linked together (see 
https://bugs.llvm.org/show_bug.cgi?id=41506 for more details).

https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=vs-2019#alignment


Repository:
  rC Clang

https://reviews.llvm.org/D61225

Files:
  lib/AST/ASTContext.cpp


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<VarDecl>(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
+            }
+          }
+        }
       }
     }
 


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<VarDecl>(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
+            }
+          }
+        }
       }
     }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to