From 5d07e0448e38d4be0cc7b1079d72b5e3644e941c Mon Sep 17 00:00:00 2001 From: Wolfgang Pieb Date: Mon, 6 Feb 2023 13:50:37 -0800 Subject: [PATCH] [TLS]: Clamp the alignment of TLS global variables if required by the target Adding a module flag 'MaxTLSAlign' describing the maximum alignment a global TLS variable can have. Optimizers are prevented from increasing the alignment of such variables beyond this threshold. Reviewed By: probinson Differential Revision: https://reviews.llvm.org/D140123 --- clang/lib/CodeGen/CodeGenModule.cpp | 4 ++++ clang/test/CodeGen/tls-maxalign-modflag.c | 12 ++++++++++++ llvm/include/llvm/IR/Module.h | 2 ++ llvm/lib/IR/Module.cpp | 7 +++++++ llvm/lib/Transforms/Utils/Local.cpp | 6 ++++++ llvm/test/CodeGen/X86/tls-align.ll | 20 ++++++++++++++++++++ 6 files changed, 51 insertions(+) create mode 100644 clang/test/CodeGen/tls-maxalign-modflag.c create mode 100644 llvm/test/CodeGen/X86/tls-align.ll diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 57c9e58..0f93c33 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -947,6 +947,10 @@ void CodeGenModule::Release() { 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()); diff --git a/clang/test/CodeGen/tls-maxalign-modflag.c b/clang/test/CodeGen/tls-maxalign-modflag.c new file mode 100644 index 0000000..d2936b6 --- /dev/null +++ b/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]] diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h index cd71a84..e868804 100644 --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -923,6 +923,8 @@ public: unsigned getOverrideStackAlignment() const; void setOverrideStackAlignment(unsigned Align); + unsigned getMaxTLSAlignment() const; + /// @name Utility functions for querying and setting the build SDK version /// @{ diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index 49fadc9..3df1e7b 100644 --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -746,6 +746,13 @@ unsigned Module::getOverrideStackAlignment() const { 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); } diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 624907a..ddef654 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -1423,6 +1423,12 @@ static Align tryEnforceAlignment(Value *V, Align PrefAlign, 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; } diff --git a/llvm/test/CodeGen/X86/tls-align.ll b/llvm/test/CodeGen/X86/tls-align.ll new file mode 100644 index 0000000..3c8ee6b --- /dev/null +++ b/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} -- 2.7.4