Skip to content

Commit 5d07e04

Browse files
author
Wolfgang Pieb
committed
[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
1 parent 66b8d2b commit 5d07e04

File tree

6 files changed

+51
-0
lines changed

6 files changed

+51
-0
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,10 @@ void CodeGenModule::Release() {
947947
if (getCodeGenOpts().SkipRaxSetup)
948948
getModule().addModuleFlag(llvm::Module::Override, "SkipRaxSetup", 1);
949949

950+
if (getContext().getTargetInfo().getMaxTLSAlign())
951+
getModule().addModuleFlag(llvm::Module::Error, "MaxTLSAlign",
952+
getContext().getTargetInfo().getMaxTLSAlign());
953+
950954
getTargetCodeGenInfo().emitTargetMetadata(*this, MangledDeclNames);
951955

952956
EmitBackendOptionsMetadata(getCodeGenOpts());
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// REQUIRES: x86-registered-target
2+
3+
// Test that we get the module flag TLSMaxAlign on the PS platforms.
4+
// RUN: %clang_cc1 -triple x86_64-scei-ps4 -S -emit-llvm -o - %s | FileCheck %s
5+
// RUN: %clang_cc1 -triple x86_64-scei-ps5 -S -emit-llvm -o - %s | FileCheck %s
6+
7+
int main(void) {
8+
return 0;
9+
}
10+
11+
// CHECK-DAG: ![[MDID:[0-9]+]] = !{i32 1, !"MaxTLSAlign", i32 256}
12+
// CHECK-DAG: llvm.module.flags = {{.*}}![[MDID]]

llvm/include/llvm/IR/Module.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,8 @@ class LLVM_EXTERNAL_VISIBILITY Module {
923923
unsigned getOverrideStackAlignment() const;
924924
void setOverrideStackAlignment(unsigned Align);
925925

926+
unsigned getMaxTLSAlignment() const;
927+
926928
/// @name Utility functions for querying and setting the build SDK version
927929
/// @{
928930

llvm/lib/IR/Module.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,13 @@ unsigned Module::getOverrideStackAlignment() const {
746746
return 0;
747747
}
748748

749+
unsigned Module::getMaxTLSAlignment() const {
750+
Metadata *MD = getModuleFlag("MaxTLSAlign");
751+
if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
752+
return CI->getZExtValue();
753+
return 0;
754+
}
755+
749756
void Module::setOverrideStackAlignment(unsigned Align) {
750757
addModuleFlag(ModFlagBehavior::Error, "override-stack-alignment", Align);
751758
}

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,6 +1423,12 @@ static Align tryEnforceAlignment(Value *V, Align PrefAlign,
14231423
if (!GO->canIncreaseAlignment())
14241424
return CurrentAlign;
14251425

1426+
if (GO->isThreadLocal()) {
1427+
unsigned MaxTLSAlign = GO->getParent()->getMaxTLSAlignment() / CHAR_BIT;
1428+
if (MaxTLSAlign && PrefAlign > Align(MaxTLSAlign))
1429+
PrefAlign = Align(MaxTLSAlign);
1430+
}
1431+
14261432
GO->setAlignment(PrefAlign);
14271433
return PrefAlign;
14281434
}

llvm/test/CodeGen/X86/tls-align.ll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; REQUIRES: x86-registered-target
2+
; RUN: opt -passes=instcombine -S < %s | FileCheck %s
3+
4+
%class.Arr = type <{ [160 x %class.Derived], i32, [4 x i8] }>
5+
%class.Derived = type { %class.Base, ptr }
6+
%class.Base = type { ptr }
7+
8+
@array = hidden thread_local global %class.Arr zeroinitializer, align 32
9+
; CHECK: @array{{.*}}align 32
10+
11+
@_ZTV7Derived = constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr null, ptr null] }, align 8
12+
13+
define internal fastcc void @foo() unnamed_addr {
14+
entry:
15+
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
16+
ret void
17+
}
18+
19+
!llvm.module.flags = !{!0}
20+
!0 = !{i32 1, !"MaxTLSAlign", i32 256}

0 commit comments

Comments
 (0)