[clang] 71b3b32 - [Clang] [MS] Add /Zc:tlsGuards option to control tls guard emission (#113830)

via cfe-commits cfe-commits at lists.llvm.org
Sat Nov 16 08:15:50 PST 2024


Author: Maurice Heumann
Date: 2024-11-16T17:15:47+01:00
New Revision: 71b3b32c6ec8e4691b67b2571b4f44cdd15cb588

URL: https://github.com/llvm/llvm-project/commit/71b3b32c6ec8e4691b67b2571b4f44cdd15cb588
DIFF: https://github.com/llvm/llvm-project/commit/71b3b32c6ec8e4691b67b2571b4f44cdd15cb588.diff

LOG: [Clang] [MS] Add /Zc:tlsGuards option to control tls guard emission (#113830)

This adds an option to control whether guards for on-demand TLS
initialization in combination with Microsoft's CXX ABI are emitted or
not.
The behaviour should match with Microsoft:
https://learn.microsoft.com/en-us/cpp/build/reference/zc-tlsguards?view=msvc-170

This fixes #103484

Added: 
    

Modified: 
    clang/include/clang/Basic/CodeGenOptions.def
    clang/include/clang/Driver/Options.td
    clang/lib/CodeGen/MicrosoftCXXABI.cpp
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/test/CodeGenCXX/ms-thread_local.cpp
    clang/test/Driver/cl-zc.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index e45370bde74a5d..4cf22c4ee08ce0 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -155,6 +155,7 @@ VALUE_CODEGENOPT(PatchableFunctionEntryOffset , 32, 0)
 CODEGENOPT(HotPatch, 1, 0) ///< Supports the Microsoft /HOTPATCH flag and
                            ///< generates a 'patchable-function' attribute.
 
+CODEGENOPT(TlsGuards , 1, 1) ///< Controls emission of tls guards via -fms-tls-guards
 CODEGENOPT(JMCInstrument, 1, 0) ///< Set when -fjmc is enabled.
 CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled.
 CODEGENOPT(CallFEntry , 1, 0) ///< Set when -mfentry is enabled.

diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 0a94a7185df8c7..d7230dd7272fd6 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4072,6 +4072,11 @@ defm threadsafe_statics : BoolFOption<"threadsafe-statics",
   NegFlag<SetFalse, [], [ClangOption, CC1Option],
           "Do not emit code to make initialization of local statics thread safe">,
   PosFlag<SetTrue>>;
+defm ms_tls_guards : BoolFOption<"ms-tls-guards",
+  CodeGenOpts<"TlsGuards">, DefaultTrue,
+  NegFlag<SetFalse, [], [CC1Option],
+          "Do not emit code to perform on-demand initialization of thread-local variables">,
+  PosFlag<SetTrue>>;
 def ftime_report : Flag<["-"], "ftime-report">, Group<f_Group>,
   Visibility<[ClangOption, CC1Option]>,
   MarshallingInfoFlag<CodeGenOpts<"TimePasses">>;
@@ -8635,6 +8640,12 @@ def _SLASH_Zc_threadSafeInit : CLFlag<"Zc:threadSafeInit">,
 def _SLASH_Zc_threadSafeInit_ : CLFlag<"Zc:threadSafeInit-">,
   HelpText<"Disable thread-safe initialization of static variables">,
   Alias<fno_threadsafe_statics>;
+def _SLASH_Zc_tlsGuards : CLFlag<"Zc:tlsGuards">,
+  HelpText<"Enable on-demand initialization of thread-local variables">,
+  Alias<fms_tls_guards>;
+def _SLASH_Zc_tlsGuards_ : CLFlag<"Zc:tlsGuards-">,
+  HelpText<"Disable on-demand initialization of thread-local variables">,
+  Alias<fno_ms_tls_guards>;
 def _SLASH_Zc_trigraphs : CLFlag<"Zc:trigraphs">,
   HelpText<"Enable trigraphs">, Alias<ftrigraphs>;
 def _SLASH_Zc_trigraphs_off : CLFlag<"Zc:trigraphs-">,

diff  --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 3802dc8bcafc49..d587daac5a88a9 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -431,6 +431,7 @@ class MicrosoftCXXABI : public CGCXXABI {
   bool usesThreadWrapperFunction(const VarDecl *VD) const override {
     return getContext().getLangOpts().isCompatibleWithMSVC(
                LangOptions::MSVC2019_5) &&
+           CGM.getCodeGenOpts().TlsGuards &&
            (!isEmittedWithConstantInitializer(VD) || mayNeedDestruction(VD));
   }
   LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD,

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 3133b8f5762389..d3eec9fea0d498 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7317,6 +7317,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
                         (!IsWindowsMSVC || IsMSVC2015Compatible)))
     CmdArgs.push_back("-fno-threadsafe-statics");
 
+  if (!Args.hasFlag(options::OPT_fms_tls_guards, options::OPT_fno_ms_tls_guards,
+                    true))
+    CmdArgs.push_back("-fno-ms-tls-guards");
+
   // Add -fno-assumptions, if it was specified.
   if (!Args.hasFlag(options::OPT_fassumptions, options::OPT_fno_assumptions,
                     true))

diff  --git a/clang/test/CodeGenCXX/ms-thread_local.cpp b/clang/test/CodeGenCXX/ms-thread_local.cpp
index cb0e8720c19b8b..1e1d1db0744b29 100644
--- a/clang/test/CodeGenCXX/ms-thread_local.cpp
+++ b/clang/test/CodeGenCXX/ms-thread_local.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 %s -std=c++1y -triple=i686-pc-win32 -fms-compatibility-version=19.25 -emit-llvm -o - | FileCheck %s
 // RUN: %clang_cc1 %s -std=c++1y -triple=i686-pc-win32 -fms-compatibility-version=19.20 -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-LEGACY
+// RUN: %clang_cc1 %s -std=c++1y -triple=i686-pc-win32 -fms-compatibility-version=19.25 -fno-ms-tls-guards -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-NO-GUARDS
 // RUN: %clang_cc1 %s -std=c++1y -triple=i686-pc-win32 -fms-compatibility-version=19.25 -ftls-model=local-dynamic -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-LD
 
 struct A {
@@ -23,17 +24,20 @@ thread_local A a = A();
 // CHECK-LD-DAG: @"__tls_init$initializer$" = internal constant ptr @__tls_init, section ".CRT$XDU"
 // CHECK-LD-DAG: @__tls_guard = external dso_local thread_local global i8
 // CHECK-LEGACY-NOT: @__tls_guard = external dso_local thread_local global i8
+// CHECK-NO-GUARDS-NOT: @__tls_guard = external dso_local thread_local global i8
 thread_local A b;
 
 // CHECK-LABEL: declare dso_local void @__dyn_tls_on_demand_init()
 // CHECK-LD-LABEL: declare dso_local void @__dyn_tls_on_demand_init()
 // CHECK-LEGACY-NOT: declare dso_local void @__dyn_tls_on_demand_init()
+// CHECK-NO-GUARDS-NOT: declare dso_local void @__dyn_tls_on_demand_init()
 
 // CHECK-LABEL: define dso_local void @"?f@@YA?AUA@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.A) align 1 %agg.result)
 // CHECK: call void @__dyn_tls_on_demand_init()
 // CHECK-LD-LABEL: define dso_local void @"?f@@YA?AUA@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.A) align 1 %agg.result)
 // CHECK-LD: call void @__dyn_tls_on_demand_init()
 // CHECK-LEGACY-NOT: call void @__dyn_tls_on_demand_init()
+// CHECK-NO-GUARDS-NOT: call void @__dyn_tls_on_demand_init()
 
 thread_local A &c = b;
 thread_local A &d = c;

diff  --git a/clang/test/Driver/cl-zc.cpp b/clang/test/Driver/cl-zc.cpp
index 9b1ea53888ceb5..5f0cd5e00819dd 100644
--- a/clang/test/Driver/cl-zc.cpp
+++ b/clang/test/Driver/cl-zc.cpp
@@ -99,6 +99,9 @@
 // RUN: %clang_cl /Zc:threadSafeInit /c -### -- %s 2>&1 | FileCheck -check-prefix=ThreadSafeStatics %s
 // ThreadSafeStatics-NOT: "-fno-threadsafe-statics"
 
+// RUN: %clang_cl /Zc:tlsGuards- /c -### -- %s 2>&1 | FileCheck -check-prefix=NoTlsGuards %s
+// NoTlsGuards: "-fno-ms-tls-guards"
+
 // RUN: %clang_cl /Zc:dllexportInlines- /c -### -- %s 2>&1 | FileCheck -check-prefix=NoDllExportInlines %s
 // NoDllExportInlines: "-fno-dllexport-inlines"
 // RUN: %clang_cl /Zc:dllexportInlines /c -### -- %s 2>&1 | FileCheck -check-prefix=DllExportInlines %s


        


More information about the cfe-commits mailing list