Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -942,6 +942,10 @@ if (getCodeGenOpts().SkipRaxSetup) getModule().addModuleFlag(llvm::Module::Override, "SkipRaxSetup", 1); + if (getContext().getTargetInfo().getMaxTLSAlign()) + getModule().addModuleFlag(llvm::Module::Error, "MaxTLSAlign", + getContext().getTargetInfo().getMaxTLSAlign()); + getTargetCodeGenInfo().emitTargetMetadata(*this, MangledDeclNames); EmitBackendOptionsMetadata(getCodeGenOpts()); Index: clang/test/CodeGen/tls-maxalign-modflag.c =================================================================== --- /dev/null +++ clang/test/CodeGen/tls-maxalign-modflag.c @@ -0,0 +1,12 @@ +// REQUIRES: x86-registered-target + +// Test that we get the module flag TLSMaxAlign on the PS platforms. +// RUN: %clang_cc1 -triple x86_64-scei-ps4 -S -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-scei-ps5 -S -emit-llvm -o - %s | FileCheck %s + +int main(void) { + return 0; +} + +// CHECK-DAG: ![[MDID:[0-9]+]] = !{i32 1, !"MaxTLSAlign", i32 256} +// CHECK-DAG: llvm.module.flags = {{.*}}![[MDID]] Index: llvm/include/llvm/IR/Module.h =================================================================== --- llvm/include/llvm/IR/Module.h +++ llvm/include/llvm/IR/Module.h @@ -923,6 +923,8 @@ unsigned getOverrideStackAlignment() const; void setOverrideStackAlignment(unsigned Align); + unsigned getMaxTLSAlignment() const; + /// @name Utility functions for querying and setting the build SDK version /// @{ Index: llvm/lib/IR/Module.cpp =================================================================== --- llvm/lib/IR/Module.cpp +++ llvm/lib/IR/Module.cpp @@ -746,6 +746,13 @@ return 0; } +unsigned Module::getMaxTLSAlignment() const { + Metadata *MD = getModuleFlag("MaxTLSAlign"); + if (auto *CI = mdconst::dyn_extract_or_null(MD)) + return CI->getZExtValue(); + return 0; +} + void Module::setOverrideStackAlignment(unsigned Align) { addModuleFlag(ModFlagBehavior::Error, "override-stack-alignment", Align); } Index: llvm/lib/Transforms/Utils/Local.cpp =================================================================== --- llvm/lib/Transforms/Utils/Local.cpp +++ llvm/lib/Transforms/Utils/Local.cpp @@ -1422,6 +1422,12 @@ if (!GO->canIncreaseAlignment()) return CurrentAlign; + if (GO->isThreadLocal()) { + unsigned MaxTLSAlign = GO->getParent()->getMaxTLSAlignment() / CHAR_BIT; + if (MaxTLSAlign && PrefAlign > Align(MaxTLSAlign)) + PrefAlign = Align(MaxTLSAlign); + } + GO->setAlignment(PrefAlign); return PrefAlign; } Index: llvm/test/CodeGen/X86/tls-align.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/X86/tls-align.ll @@ -0,0 +1,20 @@ +; REQUIRES: x86-registered-target +; RUN: opt -passes=instcombine -S < %s | FileCheck %s + +%class.Arr = type <{ [160 x %class.Derived], i32, [4 x i8] }> +%class.Derived = type { %class.Base, ptr } +%class.Base = type { ptr } + +@array = hidden thread_local global %class.Arr zeroinitializer, align 32 +; CHECK: @array{{.*}}align 32 + +@_ZTV7Derived = constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr null, ptr null] }, align 8 + +define internal fastcc void @foo() unnamed_addr { +entry: + store <8 x ptr> , ptr @array, align 32 + ret void +} + +!llvm.module.flags = !{!0} +!0 = !{i32 1, !"MaxTLSAlign", i32 256}