[llvm] 5d07e04 - [TLS]: Clamp the alignment of TLS global variables if required by the target

Wolfgang Pieb via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 8 10:40:31 PST 2023


Author: Wolfgang Pieb
Date: 2023-02-08T10:34:56-08:00
New Revision: 5d07e0448e38d4be0cc7b1079d72b5e3644e941c

URL: https://github.com/llvm/llvm-project/commit/5d07e0448e38d4be0cc7b1079d72b5e3644e941c
DIFF: https://github.com/llvm/llvm-project/commit/5d07e0448e38d4be0cc7b1079d72b5e3644e941c.diff

LOG: [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

Added: 
    clang/test/CodeGen/tls-maxalign-modflag.c
    llvm/test/CodeGen/X86/tls-align.ll

Modified: 
    clang/lib/CodeGen/CodeGenModule.cpp
    llvm/include/llvm/IR/Module.h
    llvm/lib/IR/Module.cpp
    llvm/lib/Transforms/Utils/Local.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 57c9e589be3ba..0f93c33194353 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 0000000000000..d2936b66eda6d
--- /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 cd71a848addbb..e86880406b7ea 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -923,6 +923,8 @@ class LLVM_EXTERNAL_VISIBILITY Module {
   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 49fadc9ed7e63..3df1e7b23625a 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<ConstantInt>(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 624907a691de1..ddef654ca73cc 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 0000000000000..3c8ee6b3f8ab2
--- /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 }
+
+ at array = hidden thread_local global %class.Arr zeroinitializer, align 32
+; CHECK: @array{{.*}}align 32
+
+ at _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 getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV7Derived, i64 0, inrange i32 0, i64 2), ptr null, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV7Derived, i64 0, inrange i32 0, i64 2), ptr null, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV7Derived, i64 0, inrange i32 0, i64 2), ptr null, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV7Derived, i64 0, inrange i32 0, i64 2), ptr null>, ptr @array, align 32
+  ret void
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"MaxTLSAlign", i32 256}


        


More information about the llvm-commits mailing list