https://github.com/zmodem created 
https://github.com/llvm/llvm-project/pull/196505

This fixes two issues where Clang was both over- and under-aligning variables:

1) We were applying the x86_64 psABI "large array" alignment increase (default 
when inheriting from X86_64TargetInfo), but MSVC doesn't follow that ABI.

2) MSVC implements a similar scheme though, where it increases the alignment of 
large objects. This is documented for ARM64 [1] and was implemented in Clang 
b7c6d95af5e295c560d1445e7090e31eb9289932, but it also applies to x86_64. ([2] 
says "MSVC does size (total size, not element size) based alignment for global 
symbols on ARM64 *which is copied from AMD64*").

[1] 
https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#alignment
[2] https://github.com/llvm/llvm-project/issues/40851

Fixes https://github.com/llvm/llvm-project/issues/196071
Fixes https://github.com/llvm/llvm-project/issues/171855

>From 18afb6f6f9f6f25cd2d708a495a9c112aeddf708 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <[email protected]>
Date: Fri, 8 May 2026 09:45:30 +0200
Subject: [PATCH 1/7] Don't apply the 'large array' alignment increase for
 x86_64-windows-msvc; it doesn't follow the psABI
 (https://github.com/llvm/llvm-project/issues/196071)

---
 clang/lib/Basic/Targets/X86.h     | 2 ++
 clang/test/CodeGen/align-x68_64.c | 9 +++++++++
 2 files changed, 11 insertions(+)

diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index c7afcc7c86053..e6f798834d11c 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -968,6 +968,8 @@ class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo
       : WindowsX86_64TargetInfo(Triple, Opts) {
     LongDoubleWidth = LongDoubleAlign = 64;
     LongDoubleFormat = &llvm::APFloat::IEEEdouble();
+    LargeArrayMinWidth = 0;
+    LargeArrayAlign = 0;
   }
 
   void getTargetDefines(const LangOptions &Opts,
diff --git a/clang/test/CodeGen/align-x68_64.c 
b/clang/test/CodeGen/align-x68_64.c
index cf128b43433ea..01a3f34e6d321 100644
--- a/clang/test/CodeGen/align-x68_64.c
+++ b/clang/test/CodeGen/align-x68_64.c
@@ -1,11 +1,20 @@
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | 
FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu       -emit-llvm %s -o - | 
FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc      -emit-llvm %s -o - | 
FileCheck --check-prefix=MSVC %s
 // PR5599
 
+char arr[16];
+
 void test1_f(void *);
 
 void test1_g(void) {
   float x[4];
   test1_f(x);
 }
+// CHECK: @arr = {{.*}} align 16
 // CHECK: @test1_g
 // CHECK: alloca [4 x float], align 16
+
+// MSVC: @arr = {{.*}} align 1
+// MSVC: @test1_g
+// MSVC: alloca [4 x float], align 4

>From eb30e4051f22f63b54d4b5bda6c860717067fd1c Mon Sep 17 00:00:00 2001
From: Hans Wennborg <[email protected]>
Date: Fri, 8 May 2026 10:25:40 +0200
Subject: [PATCH 2/7] implement MicrosoftX86_64TargetInfo::getMinGlobalAlign

---
 clang/lib/Basic/Targets/X86.cpp               | 21 +++++++++++++++++++
 clang/lib/Basic/Targets/X86.h                 |  3 +++
 .../CodeGen/arm64-microsoft-struct-align.cpp  |  2 ++
 3 files changed, 26 insertions(+)

diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp
index cb941c94c84a7..f0227be035ee3 100644
--- a/clang/lib/Basic/Targets/X86.cpp
+++ b/clang/lib/Basic/Targets/X86.cpp
@@ -1852,3 +1852,24 @@ X86_64TargetInfo::getTargetBuiltins() const {
        "__builtin_ia32_"},
   };
 }
+
+unsigned
+MicrosoftX86_64TargetInfo::getMinGlobalAlign(uint64_t TypeSize,
+                                             bool HasNonWeakDef) const {
+  // XXX: copy-pasted. can we share the code?
+  unsigned Align =
+      WindowsX86_64TargetInfo::getMinGlobalAlign(TypeSize, HasNonWeakDef);
+
+  // 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 (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
+  }
+  return Align;
+}
diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index e6f798834d11c..c8c5d280754b4 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -983,6 +983,9 @@ class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo
   getCallingConvKind(bool ClangABICompat4) const override {
     return CCK_MicrosoftWin64;
   }
+
+  unsigned getMinGlobalAlign(uint64_t TypeSize,
+                             bool HasNonWeakDef) const override;
 };
 
 // x86-64 MinGW target
diff --git a/clang/test/CodeGen/arm64-microsoft-struct-align.cpp 
b/clang/test/CodeGen/arm64-microsoft-struct-align.cpp
index 4076c3ca34ad7..60bb9e2fc5405 100644
--- a/clang/test/CodeGen/arm64-microsoft-struct-align.cpp
+++ b/clang/test/CodeGen/arm64-microsoft-struct-align.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -triple aarch64-windows -ffreestanding -emit-llvm -O0 \
 // RUN: -x c++ -o - %s | FileCheck %s
 
+// FIXME: add tests here.
+
 struct size1 { char str[1]; };
 struct size2 { char str[2]; };
 struct size7 { char str[4]; };

>From efa8384116d24f0f3530e0f343e226f49fb162a8 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <[email protected]>
Date: Fri, 8 May 2026 10:43:22 +0200
Subject: [PATCH 3/7] remove alignment checks from
 clang/test/CodeGen/c-strings.c

---
 clang/test/CodeGen/c-strings.c | 30 ++++--------------------------
 1 file changed, 4 insertions(+), 26 deletions(-)

diff --git a/clang/test/CodeGen/c-strings.c b/clang/test/CodeGen/c-strings.c
index 31c438fd8ff2e..60d434f37a20d 100644
--- a/clang/test/CodeGen/c-strings.c
+++ b/clang/test/CodeGen/c-strings.c
@@ -4,37 +4,15 @@
 // Should be 3 hello strings, two global (of different sizes), the rest are
 // shared.
 
-// CHECK: @align = {{(dso_local )?}}global i8 [[ALIGN:[0-9]+]]
 // ITANIUM: @.str = private unnamed_addr constant [6 x i8] c"hello\00"
-// MSABI: @"??_C@_05CJBACGMB@hello?$AA@" = linkonce_odr dso_local unnamed_addr 
constant [6 x i8] c"hello\00", comdat, align 1
+// MSABI: @"??_C@_05CJBACGMB@hello?$AA@" = linkonce_odr dso_local unnamed_addr 
constant [6 x i8] c"hello\00", comdat
 // ITANIUM: @f1.x = internal global ptr @.str
 // MSABI: @f1.x = internal global ptr @"??_C@_05CJBACGMB@hello?$AA@"
-// CHECK: @f2.x = internal global [6 x i8] c"hello\00", align [[ALIGN]]
-// CHECK: @f3.x = internal global [8 x i8] c"hello\00\00\00", align [[ALIGN]]
+// CHECK: @f2.x = internal global [6 x i8] c"hello\00"
+// CHECK: @f3.x = internal global [8 x i8] c"hello\00\00\00"
 // ITANIUM: @f4.x = internal global %struct.s { ptr @.str }
 // MSABI: @f4.x = internal global %struct.s { ptr 
@"??_C@_05CJBACGMB@hello?$AA@" }
-// CHECK: @x = {{(dso_local )?}}global [3 x i8] c"ola", align [[ALIGN]]
-
-// XFAIL: target=aarch64-{{.*}}-windows-msvc, 
target=arm64ec-{{.*}}-windows-msvc
-// Arm64 in MSVC mode aligns arrays to either 32-bit or 64-bit boundaries, 
which fails
-// various checks above, since ALIGN is derived from the alignment of a single
-// i8, which is still 1.
-
-// XFAIL: target=hexagon-{{.*}}
-// Hexagon aligns arrays of size 8+ bytes to a 64-bit boundary, which
-// fails the check for "@f3.x = ... align [ALIGN]", since ALIGN is derived
-// from the alignment of a single i8, which is still 1.
-
-// XFAIL: target=csky{{.*}}
-// CSKY aligns arrays of size 4+ bytes to a 32-bit boundary, which
-// fails the check for "@f2.x = ... align [ALIGN]", since ALIGN is derived
-// from the alignment of a single i8, which is still 1.
-
-#if defined(__s390x__)
-unsigned char align = 2;
-#else
-unsigned char align = 1;
-#endif
+// CHECK: @x = {{(dso_local )?}}global [3 x i8] c"ola"
 
 void bar(const char *);
 

>From 512728acf14f772099c6a6cd1fd3b08b204383cc Mon Sep 17 00:00:00 2001
From: Hans Wennborg <[email protected]>
Date: Fri, 8 May 2026 10:51:27 +0200
Subject: [PATCH 4/7] update tests

---
 clang/test/CodeGen/align-x68_64.c                |  2 +-
 clang/test/CodeGen/asan-strings.c                |  4 ++--
 .../ms-constexpr-static-data-member.cpp          |  4 ++--
 clang/test/CodeGenObjC/encode-test-6.m           |  2 +-
 .../CodeGenSYCL/kernel-caller-entry-point.cpp    | 16 ++++++++--------
 5 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/clang/test/CodeGen/align-x68_64.c 
b/clang/test/CodeGen/align-x68_64.c
index 01a3f34e6d321..94f967b6941d8 100644
--- a/clang/test/CodeGen/align-x68_64.c
+++ b/clang/test/CodeGen/align-x68_64.c
@@ -15,6 +15,6 @@ void test1_g(void) {
 // CHECK: @test1_g
 // CHECK: alloca [4 x float], align 16
 
-// MSVC: @arr = {{.*}} align 1
+// MSVC: @arr = {{.*}} align 8
 // MSVC: @test1_g
 // MSVC: alloca [4 x float], align 4
diff --git a/clang/test/CodeGen/asan-strings.c 
b/clang/test/CodeGen/asan-strings.c
index 0c7420034f89e..e71445eaf7fe4 100644
--- a/clang/test/CodeGen/asan-strings.c
+++ b/clang/test/CodeGen/asan-strings.c
@@ -12,6 +12,6 @@ const char *foo(void) { return "asdf"; }
 
 // LINUX: @.str = private unnamed_addr constant [5 x i8] c"asdf\00", align 1
 
-// WINDOWS: @"??_C@_04JIHMPGLA@asdf?$AA@" = linkonce_odr dso_local 
unnamed_addr constant [5 x i8] c"asdf\00", comdat, align 1
+// WINDOWS: @"??_C@_04JIHMPGLA@asdf?$AA@" = linkonce_odr dso_local 
unnamed_addr constant [5 x i8] c"asdf\00", comdat, align 4
 
-// WINWRITE: @.str = private unnamed_addr global [5 x i8] c"asdf\00", align 1
+// WINWRITE: @.str = private unnamed_addr global [5 x i8] c"asdf\00", align 4
diff --git a/clang/test/CodeGenCXX/ms-constexpr-static-data-member.cpp 
b/clang/test/CodeGenCXX/ms-constexpr-static-data-member.cpp
index 604a49fefbacb..4b191fd472c20 100644
--- a/clang/test/CodeGenCXX/ms-constexpr-static-data-member.cpp
+++ b/clang/test/CodeGenCXX/ms-constexpr-static-data-member.cpp
@@ -19,8 +19,8 @@ void usethem() {
   useptr(&S::sdm_udt);
 }
 
-// CHECK-DAG: @"?sdm_char_array@S@@2QBDB" = linkonce_odr dso_local constant [5 
x i8] c"asdf\00", comdat, align 1
+// CHECK-DAG: @"?sdm_char_array@S@@2QBDB" = linkonce_odr dso_local constant [5 
x i8] c"asdf\00", comdat, align 4
 
 // CHECK-DAG: @"?sdm_char_ptr@S@@2QEBDEB" = linkonce_odr dso_local constant 
ptr @"??_C@_04JIHMPGLA@asdf?$AA@", comdat, align 8
 
-// CHECK-DAG: @"?sdm_udt@S@@2UFoo@@B" = linkonce_odr dso_local constant 
%struct.Foo { i32 1, i32 2 }, comdat, align 4
+// CHECK-DAG: @"?sdm_udt@S@@2UFoo@@B" = linkonce_odr dso_local constant 
%struct.Foo { i32 1, i32 2 }, comdat, align 8
diff --git a/clang/test/CodeGenObjC/encode-test-6.m 
b/clang/test/CodeGenObjC/encode-test-6.m
index c32f8f24c0009..dd770f523e2f3 100644
--- a/clang/test/CodeGenObjC/encode-test-6.m
+++ b/clang/test/CodeGenObjC/encode-test-6.m
@@ -80,6 +80,6 @@ @implementation SCNCamera
 // CHECK-DWARF: define{{.*}} ptr @Test()
 // CHECK-DWARF: ret ptr @e
 
-// CHECK-MSVC: @e = dso_local global [2 x i8] c"i\00", align 1
+// CHECK-MSVC: @e = dso_local global [2 x i8] c"i\00", align 4
 // CHECK-MINGW: @e = dso_local global [2 x i8] c"i\00", align 1
 // CHECK-ELF: @e = global [2 x i8] c"i\00", align 1
diff --git a/clang/test/CodeGenSYCL/kernel-caller-entry-point.cpp 
b/clang/test/CodeGenSYCL/kernel-caller-entry-point.cpp
index 410988e16acdc..528d27f85e54b 100644
--- a/clang/test/CodeGenSYCL/kernel-caller-entry-point.cpp
+++ b/clang/test/CodeGenSYCL/kernel-caller-entry-point.cpp
@@ -148,14 +148,14 @@ int main() {
 // CHECK-HOST-LINUX       @.str.5 = private unnamed_addr constant [30 x i8] 
c"_ZTS23fwd_ref_arg_kernel_name\00", align 1
 // CHECK-HOST-LINUX:      @.str.6 = private unnamed_addr constant [35 x i8] 
c"_ZTS28fwd_ref_arg_kernel_name_move\00", align 1
 // CHECK-HOST-LINUX:      @.str.7 = private unnamed_addr constant [33 x i8] 
c"_ZTS26rvalue_ref_arg_kernel_name\00", align 1
-// CHECK-HOST-WINDOWS: @"??_C@_0CB@KFIJOMLB@_ZTS26single_purpose_kernel_name@" 
= linkonce_odr dso_local unnamed_addr constant [33 x i8] 
c"_ZTS26single_purpose_kernel_name\00", comdat, align 1
-// CHECK-HOST-WINDOWS: @"??_C@_0BC@NHCDOLAA@_ZTSZ4mainEUlT_E_?$AA@" = 
linkonce_odr dso_local unnamed_addr constant [18 x i8] c"_ZTSZ4mainEUlT_E_\00", 
comdat, align 1
-// CHECK-HOST-WINDOWS: @"??_C@_0M@BCGAEMBE@_ZTS6?N?$LE?O?$IE?O?$IH?$AA@" = 
linkonce_odr dso_local unnamed_addr constant [12 x i8] 
c"_ZTS6\CE\B4\CF\84\CF\87\00", comdat, align 1
-// CHECK-HOST-WINDOWS: @"??_C@_0P@DLGHPODL@_ZTSZ4mainE2KN?$AA@" = linkonce_odr 
dso_local unnamed_addr constant [15 x i8] c"_ZTSZ4mainE2KN\00", comdat, align 1
-// CHECK-HOST-WINDOWS: @"??_C@_0BK@PPDJPOBM@_ZTS19ref_arg_kernel_name?$AA@" = 
linkonce_odr dso_local unnamed_addr constant [26 x i8] 
c"_ZTS19ref_arg_kernel_name\00", comdat, align 1
-// CHECK-HOST-WINDOWS: 
@"??_C@_0BO@KEIBIHKH@_ZTS23fwd_ref_arg_kernel_name?$AA@" = linkonce_odr 
dso_local unnamed_addr constant [30 x i8] c"_ZTS23fwd_ref_arg_kernel_name\00", 
comdat, align 1
-// CHECK-HOST-WINDOWS: @"??_C@_0CD@FDALJLMM@_ZTS28fwd_ref_arg_kernel_name_mo@" 
= linkonce_odr dso_local unnamed_addr constant [35 x i8] 
c"_ZTS28fwd_ref_arg_kernel_name_move\00", comdat, align 1
-// CHECK-HOST-WINDOWS: @"??_C@_0CB@HCPMABHM@_ZTS26rvalue_ref_arg_kernel_name@" 
= linkonce_odr dso_local unnamed_addr constant [33 x i8] 
c"_ZTS26rvalue_ref_arg_kernel_name\00", comdat, align 1
+// CHECK-HOST-WINDOWS: @"??_C@_0CB@KFIJOMLB@_ZTS26single_purpose_kernel_name@" 
= linkonce_odr dso_local unnamed_addr constant [33 x i8] 
c"_ZTS26single_purpose_kernel_name\00", comdat
+// CHECK-HOST-WINDOWS: @"??_C@_0BC@NHCDOLAA@_ZTSZ4mainEUlT_E_?$AA@" = 
linkonce_odr dso_local unnamed_addr constant [18 x i8] c"_ZTSZ4mainEUlT_E_\00", 
comdat
+// CHECK-HOST-WINDOWS: @"??_C@_0M@BCGAEMBE@_ZTS6?N?$LE?O?$IE?O?$IH?$AA@" = 
linkonce_odr dso_local unnamed_addr constant [12 x i8] 
c"_ZTS6\CE\B4\CF\84\CF\87\00", comdat
+// CHECK-HOST-WINDOWS: @"??_C@_0P@DLGHPODL@_ZTSZ4mainE2KN?$AA@" = linkonce_odr 
dso_local unnamed_addr constant [15 x i8] c"_ZTSZ4mainE2KN\00", comdat
+// CHECK-HOST-WINDOWS: @"??_C@_0BK@PPDJPOBM@_ZTS19ref_arg_kernel_name?$AA@" = 
linkonce_odr dso_local unnamed_addr constant [26 x i8] 
c"_ZTS19ref_arg_kernel_name\00", comdat
+// CHECK-HOST-WINDOWS: 
@"??_C@_0BO@KEIBIHKH@_ZTS23fwd_ref_arg_kernel_name?$AA@" = linkonce_odr 
dso_local unnamed_addr constant [30 x i8] c"_ZTS23fwd_ref_arg_kernel_name\00", 
comdat
+// CHECK-HOST-WINDOWS: @"??_C@_0CD@FDALJLMM@_ZTS28fwd_ref_arg_kernel_name_mo@" 
= linkonce_odr dso_local unnamed_addr constant [35 x i8] 
c"_ZTS28fwd_ref_arg_kernel_name_move\00", comdat
+// CHECK-HOST-WINDOWS: @"??_C@_0CB@HCPMABHM@_ZTS26rvalue_ref_arg_kernel_name@" 
= linkonce_odr dso_local unnamed_addr constant [33 x i8] 
c"_ZTS26rvalue_ref_arg_kernel_name\00", comdat
 //
 // CHECK-HOST-LINUX:      define dso_local void 
@_Z26single_purpose_kernel_task21single_purpose_kernel() #{{[0-9]+}} {
 // CHECK-HOST-LINUX-NEXT: entry:

>From 44e7c66cdaea9ea4fd1bb61ca90bebe74e235ac7 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <[email protected]>
Date: Fri, 8 May 2026 10:52:52 +0200
Subject: [PATCH 5/7] align-x68_64.c comment

---
 clang/test/CodeGen/align-x68_64.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/test/CodeGen/align-x68_64.c 
b/clang/test/CodeGen/align-x68_64.c
index 94f967b6941d8..91f5fac199136 100644
--- a/clang/test/CodeGen/align-x68_64.c
+++ b/clang/test/CodeGen/align-x68_64.c
@@ -15,6 +15,7 @@ void test1_g(void) {
 // CHECK: @test1_g
 // CHECK: alloca [4 x float], align 16
 
+// The "large array" alignment increase does not apply on windows-msvc.
 // MSVC: @arr = {{.*}} align 8
 // MSVC: @test1_g
 // MSVC: alloca [4 x float], align 4

>From 12d483afc5b8dffa2b2ec27e6fb93eee1c2ec1a6 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <[email protected]>
Date: Fri, 8 May 2026 10:58:21 +0200
Subject: [PATCH 6/7] reuse microsoft-64bit-struct-align.cpp

---
 ...ft-struct-align.cpp => microsoft-64bit-struct-align.cpp} | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
 rename clang/test/CodeGen/{arm64-microsoft-struct-align.cpp => 
microsoft-64bit-struct-align.cpp} (83%)

diff --git a/clang/test/CodeGen/arm64-microsoft-struct-align.cpp 
b/clang/test/CodeGen/microsoft-64bit-struct-align.cpp
similarity index 83%
rename from clang/test/CodeGen/arm64-microsoft-struct-align.cpp
rename to clang/test/CodeGen/microsoft-64bit-struct-align.cpp
index 60bb9e2fc5405..55abcfe9910af 100644
--- a/clang/test/CodeGen/arm64-microsoft-struct-align.cpp
+++ b/clang/test/CodeGen/microsoft-64bit-struct-align.cpp
@@ -1,7 +1,5 @@
-// RUN: %clang_cc1 -triple aarch64-windows -ffreestanding -emit-llvm -O0 \
-// RUN: -x c++ -o - %s | FileCheck %s
-
-// FIXME: add tests here.
+// RUN: %clang_cc1 -triple aarch64-windows-msvc -emit-llvm -o - %s | FileCheck 
%s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc  -emit-llvm -o - %s | FileCheck 
%s
 
 struct size1 { char str[1]; };
 struct size2 { char str[2]; };

>From 68414eccbc6cec4de9ed062dbe2b5f26c0ea7747 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <[email protected]>
Date: Fri, 8 May 2026 11:24:19 +0200
Subject: [PATCH 7/7] break out Microsoft64BitMinGlobalAlign

---
 clang/include/clang/Basic/TargetInfo.h |  2 ++
 clang/lib/Basic/TargetInfo.cpp         | 17 +++++++++++++++++
 clang/lib/Basic/Targets/AArch64.cpp    | 13 +------------
 clang/lib/Basic/Targets/X86.cpp        | 14 +-------------
 4 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 9f7d2a17a0f8a..e21155b2e4fd4 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1968,6 +1968,8 @@ class TargetInfo : public TransferrableTargetInfo,
   void CheckFixedPointBits() const;
 };
 
+unsigned Microsoft64BitMinGlobalAlign(uint64_t TypeSize);
+
 namespace targets {
 std::unique_ptr<clang::TargetInfo>
 AllocateTarget(const llvm::Triple &Triple, const clang::TargetOptions &Opts);
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index e6ae89e0948c5..d29bda889ac18 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -1114,3 +1114,20 @@ TargetInfo::simplifyConstraint(StringRef Constraint,
   }
   return Result;
 }
+
+unsigned clang::Microsoft64BitMinGlobalAlign(uint64_t TypeSize) {
+  // 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
+  // The same is done for x64, but not documented.
+
+  if (TypeSize >= 512) // TypeSize >= 64 bytes
+    return 128;        // align type at least 16 bytes
+  if (TypeSize >= 64)  // TypeSize >= 8 bytes
+    return 64;         // align type at least 8 butes
+  if (TypeSize >= 16)  // TypeSize >= 2 bytes
+    return 32;         // align type at least 4 bytes
+
+  return 0;
+}
diff --git a/clang/lib/Basic/Targets/AArch64.cpp 
b/clang/lib/Basic/Targets/AArch64.cpp
index 9b951e69cce33..9afe6cb10729d 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -1815,18 +1815,7 @@ unsigned 
MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize,
   unsigned Align =
       WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize, HasNonWeakDef);
 
-  // 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 (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
-  }
-  return Align;
+  return std::max(Align, Microsoft64BitMinGlobalAlign(TypeSize));
 }
 
 MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp
index f0227be035ee3..60c001a826078 100644
--- a/clang/lib/Basic/Targets/X86.cpp
+++ b/clang/lib/Basic/Targets/X86.cpp
@@ -1856,20 +1856,8 @@ X86_64TargetInfo::getTargetBuiltins() const {
 unsigned
 MicrosoftX86_64TargetInfo::getMinGlobalAlign(uint64_t TypeSize,
                                              bool HasNonWeakDef) const {
-  // XXX: copy-pasted. can we share the code?
   unsigned Align =
       WindowsX86_64TargetInfo::getMinGlobalAlign(TypeSize, HasNonWeakDef);
 
-  // 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 (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
-  }
-  return Align;
+  return std::max(Align, Microsoft64BitMinGlobalAlign(TypeSize));
 }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to