llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clangir

Author: Erich Keane (erichkeane)

<details>
<summary>Changes</summary>

Functionally, the only difference between these models is the tag that goes 
onto the variable in the LLVM-IR. This patch changes our "== GeneralDynamic" 
checks to just be whether they have a TLS Model defined, so all the previous 
logic still holds.

This patch DOES have to add the 'default' model to the module, as the top-level 
TLS guard needs to have this model, even if the individual variables are 
overridden by the tls_model attribute.

Like the previous inline-printing patch, this ensures we print the module 
result attribute as an enum value instead an integral. This requires some 
custom parse/printing here, but is pretty routine. We can't convert GlobalOp 
without vastly changing how it prints these, as there isn't really a 
'assemblyFormat' that works for this printed as an 'attribute' and a keyword.

We ALSO had to change the name of the enum to be TLSModel, because MLIR is 
inconsistent in tablegen where it gets the name from on an enum, so it would 
pick up the wrong spelling sometimes.

---

Patch is 32.48 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/215380.diff


13 Files Affected:

- (modified) clang/include/clang/CIR/Dialect/IR/CIRDialect.td (+1) 
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+14-4) 
- (modified) clang/lib/CIR/CodeGen/CIRGenDeclCXX.cpp (-3) 
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+17-13) 
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.h (+1-1) 
- (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+25-1) 
- (modified) clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp (+15-12) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/global-ctor-dtor.cpp (+1-1) 
- (added) clang/test/CIR/CodeGen/tls-model-func-scope.cpp (+79) 
- (modified) clang/test/CIR/CodeGen/tls-model.cpp (+27-31) 
- (modified) clang/test/CIR/IR/global.cir (+8) 
- (modified) clang/test/CIR/IR/invalid-tls.cir (+6-3) 


``````````diff
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td 
b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
index de90fed45f170..d9319a44d017e 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
@@ -86,6 +86,7 @@ def CIR_Dialect : Dialect {
     static llvm::StringRef getAMDGPUXnackAttrName() { return 
"cir.amdgpu_xnack"; }
     static llvm::StringRef getAMDGPUSramEccAttrName() { return 
"cir.amdgpu_sramecc"; }
     static llvm::StringRef getOpenCLKernelArgMetadataAttrName() { return 
"cir.cl.kernel_arg_metadata"; }
+    static llvm::StringRef getDefaultTlsModelAttrName() { return 
"cir.default.tls_model"; }
 
     void registerAttributes();
     void registerTypes();
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index d0f3c9ee6715f..53f9dccbba1a0 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -3301,12 +3301,22 @@ def CIR_GlobalLinkageKind : CIR_I32EnumAttr<
 // properties of a global variable will be added over time as more of ClangIR
 // is upstreamed.
 
-def CIR_TLSModel : CIR_I32EnumAttr<"TLS_Model", "TLS model", [
+def CIR_TLSModel : CIR_I32EnumAttr<"TLSModel", "TLS model", [
   I32EnumAttrCase<"GeneralDynamic", 1, "tls_dyn">,
   I32EnumAttrCase<"LocalDynamic", 2, "tls_local_dyn">,
   I32EnumAttrCase<"InitialExec", 3, "tls_init_exec">,
   I32EnumAttrCase<"LocalExec", 4, "tls_local_exec">
-]>;
+  ]> {
+  let genSpecializedAttr = 0;
+}
+
+def CIR_TLSModelAttr: CIR_EnumAttr<CIR_TLSModel, "tls_model"> {
+  let summary = "TLS Model attribute";
+  let description = [{
+     The TLS mode for the global, which comes from either the
+    `tls_model` attribute, or `-ftls-model` flag.
+  }];
+}
 
 def CIR_GlobalOp : CIR_Op<"global", [
   DeclareOpInterfaceMethods<RegionBranchOpInterface, ["getSuccessorInputs"]>,
@@ -3347,7 +3357,7 @@ def CIR_GlobalOp : CIR_Op<"global", [
                        TypeAttr:$sym_type,
                        CIR_GlobalLinkageKind:$linkage,
                        OptionalAttr<MemorySpaceAttrInterface>:$addr_space,
-                       OptionalAttr<CIR_TLSModel>:$tls_model,
+                       OptionalAttr<CIR_TLSModelAttr>:$tls_model,
                        
OptionalAttr<CIR_ThreadLocalGlobalWrapperInitAttr>:$dyn_tls_refs,
                        OptionalAttr<AnyAttr>:$initial_value,
                        UnitProp:$comdat,
@@ -3371,7 +3381,7 @@ def CIR_GlobalOp : CIR_Op<"global", [
     (`constant` $constant^)?
     $linkage
     (`comdat` $comdat^)?
-    ($tls_model^)?
+    (` ` custom<TLSModel>($tls_model)^ )?
     (`dyn_tls_refs` `=` $dyn_tls_refs^)?
     (`dso_local` $dso_local^)?
     (`static_local_guard` `` $static_local_guard^)?
diff --git a/clang/lib/CIR/CodeGen/CIRGenDeclCXX.cpp 
b/clang/lib/CIR/CodeGen/CIRGenDeclCXX.cpp
index 03929e50f44f9..1e31877e51b74 100644
--- a/clang/lib/CIR/CodeGen/CIRGenDeclCXX.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenDeclCXX.cpp
@@ -68,9 +68,6 @@ void CIRGenModule::setGlobalTlsReferences(const VarDecl &vd,
   if (!getLangOpts().CPlusPlus)
     return;
 
-  if (globalOp.getTlsModel() != cir::TLS_Model::GeneralDynamic)
-    return;
-
   llvm::SmallString<256> wrapperFuncName;
   llvm::SmallString<256> initFuncName;
   llvm::SmallString<256> guardName;
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp 
b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index ae9cad0b7c30f..dfb47fb4cda62 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -144,6 +144,10 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
                                              cgo.OptimizationLevel,
                                              cgo.OptimizeSize));
 
+  theModule->setAttr(
+      cir::CIRDialect::getDefaultTlsModelAttrName(),
+      cir::TLSModelAttr::get(&mlirContext, getDefaultCIRTLSModel()));
+
   if (langOpts.OpenMP) {
     mlir::omp::OffloadModuleOpts ompOpts(
         langOpts.OpenMPTargetDebug, langOpts.OpenMPTeamSubscription,
@@ -3070,24 +3074,24 @@ bool CIRGenModule::lookupRepresentativeDecl(StringRef 
mangledName,
   return true;
 }
 
-static cir::TLS_Model getCIRTLSModel(StringRef S) {
-  return llvm::StringSwitch<cir::TLS_Model>(S)
-      .Case("global-dynamic", cir::TLS_Model::GeneralDynamic)
-      .Case("local-dynamic", cir::TLS_Model::LocalDynamic)
-      .Case("initial-exec", cir::TLS_Model::InitialExec)
-      .Case("local-exec", cir::TLS_Model::LocalExec);
+static cir::TLSModel getCIRTLSModel(StringRef S) {
+  return llvm::StringSwitch<cir::TLSModel>(S)
+      .Case("global-dynamic", cir::TLSModel::GeneralDynamic)
+      .Case("local-dynamic", cir::TLSModel::LocalDynamic)
+      .Case("initial-exec", cir::TLSModel::InitialExec)
+      .Case("local-exec", cir::TLSModel::LocalExec);
 }
 
-cir::TLS_Model CIRGenModule::getDefaultCIRTLSModel() const {
+cir::TLSModel CIRGenModule::getDefaultCIRTLSModel() const {
   switch (getCodeGenOpts().getDefaultTLSModel()) {
   case CodeGenOptions::GeneralDynamicTLSModel:
-    return cir::TLS_Model::GeneralDynamic;
+    return cir::TLSModel::GeneralDynamic;
   case CodeGenOptions::LocalDynamicTLSModel:
-    return cir::TLS_Model::LocalDynamic;
+    return cir::TLSModel::LocalDynamic;
   case CodeGenOptions::InitialExecTLSModel:
-    return cir::TLS_Model::InitialExec;
+    return cir::TLSModel::InitialExec;
   case CodeGenOptions::LocalExecTLSModel:
-    return cir::TLS_Model::LocalExec;
+    return cir::TLSModel::LocalExec;
   }
   llvm_unreachable("Invalid TLS model!");
 }
@@ -3096,7 +3100,7 @@ void CIRGenModule::setTLSMode(mlir::Operation *op, const 
VarDecl &d,
                               bool isExtendingDecl) {
   assert(d.getTLSKind() && "setting TLS mode on non-TLS var!");
 
-  cir::TLS_Model tlm = getDefaultCIRTLSModel();
+  cir::TLSModel tlm = getDefaultCIRTLSModel();
 
   // Override the TLS model if it is explicitly specified.
   if (const auto *attr = d.getAttr<TLSModelAttr>())
@@ -3107,7 +3111,7 @@ void CIRGenModule::setTLSMode(mlir::Operation *op, const 
VarDecl &d,
 
   // For namespace-scope dyanmic TLS we need to set the wrapper, int, or guard
   // info.
-  if (d.isStaticLocal() || tlm != cir::TLS_Model::GeneralDynamic)
+  if (d.isStaticLocal())
     return;
 
   // If this function was called to set the TLS mode for a temporary whose
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h 
b/clang/lib/CIR/CodeGen/CIRGenModule.h
index ba7b20b91cc03..9d19a58a05b4d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -637,7 +637,7 @@ class CIRGenModule : public CIRGenTypeCache {
                   bool isExtendingDecl = false);
 
   /// Get TLS mode from CodeGenOptions.
-  cir::TLS_Model getDefaultCIRTLSModel() const;
+  cir::TLSModel getDefaultCIRTLSModel() const;
 
   /// Set function attributes for a function declaration.
   void setFunctionAttributes(GlobalDecl gd, cir::FuncOp f,
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index cd94219655e02..3a0b07c1daa1f 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -287,6 +287,30 @@ parseGlobalAddressSpaceValue(mlir::AsmParser &p,
 void printGlobalAddressSpaceValue(mlir::AsmPrinter &printer, cir::GlobalOp op,
                                   mlir::ptr::MemorySpaceAttrInterface attr);
 
+mlir::OptionalParseResult parseTLSModel(mlir::AsmParser &parser,
+                                        cir::TLSModelAttr &attr) {
+  static constexpr llvm::StringRef keywords[] = {
+      "tls_dyn", "tls_local_dyn", "tls_init_exec", "tls_local_exec"};
+  llvm::StringRef keyword;
+  if (parser.parseOptionalKeyword(&keyword, keywords).failed())
+    return success();
+
+  auto tlsModel = ::cir::symbolizeEnum<::cir::TLSModel>(keyword);
+  if (!tlsModel) {
+    return parser.emitError(parser.getCurrentLocation(), "expected one of [")
+           << llvm::join(llvm::ArrayRef(keywords), ", ")
+           << "] for TLSModel, got: " << keyword;
+  }
+
+  attr = ::cir::TLSModelAttr::get(parser.getContext(), *tlsModel);
+  return success();
+}
+
+void printTLSModel(mlir::AsmPrinter &printer, cir::GlobalOp op,
+                   const cir::TLSModelAttr &attr) {
+  printer << " " << stringifyTLSModel(attr.getValue());
+}
+
 
//===----------------------------------------------------------------------===//
 // AllocaOp
 
//===----------------------------------------------------------------------===//
@@ -2099,7 +2123,7 @@ mlir::LogicalResult cir::GlobalOp::verify() {
     if (getStaticLocalGuard().has_value())
       return emitOpError(
           "cannot have both static local and dynamic tls references");
-    if (!getTlsModel() || getTlsModel() != TLS_Model::GeneralDynamic)
+    if (!getTlsModel())
       return emitOpError("'dyn_tls_refs' only valid for dynamic tls");
   }
 
diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp 
b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
index 12d544fecbcc9..9628c64595e55 100644
--- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
@@ -1460,9 +1460,9 @@ void 
LoweringPreparePass::lowerLocalInitOp(cir::LocalInitOp initOp) {
   // Remove the init local op, now that we've done everything we need with it.
   initOp.erase();
 }
-static bool isThreadWrapperReplaceable(cir::TLS_Model tls,
+static bool isThreadWrapperReplaceable(cir::TLSModel tls,
                                        clang::ASTContext &astCtx) {
-  return tls == cir::TLS_Model::GeneralDynamic &&
+  return tls == cir::TLSModel::GeneralDynamic &&
          astCtx.getTargetInfo().getTriple().isOSDarwin();
 }
 
@@ -1613,8 +1613,7 @@ void LoweringPreparePass::lowerGlobalOp(GlobalOp op) {
     dtorRegion.getBlocks().clear();
 
     assert(!cir::MissingFeatures::astVarDeclInterface());
-    if (op.getTlsModel() == TLS_Model::GeneralDynamic &&
-        !op.getStaticLocalGuard().has_value()) {
+    if (op.getTlsModel() && !op.getStaticLocalGuard().has_value()) {
       // There are two types of global TLS variables: 'ordered' and 
'unordered'.
       // 'ordered' are the common case. A call to any of them causes all of the
       // initializers for all other 'ordered' ones to be called, via a
@@ -1640,8 +1639,7 @@ void LoweringPreparePass::lowerGlobalOp(GlobalOp op) {
     } else {
       dynamicInitializers.push_back(f);
     }
-  } else if (op.getTlsModel() == TLS_Model::GeneralDynamic &&
-             op.getDynTlsRefs() && op.isDeclaration()) {
+  } else if (op.getTlsModel() && op.getDynTlsRefs() && op.isDeclaration()) {
     // If this is a declaration and has no init function, we probably DO have 
to
     // create an alias that needs checking, so create it as extern-weak.
     initAlias = defineGlobalThreadLocalInitAlias(op, {});
@@ -1650,7 +1648,7 @@ void LoweringPreparePass::lowerGlobalOp(GlobalOp op) {
   // We need a wrapper for TLS globals that MIGHT have a non-constant
   // initialization. The FE will have generated the DynTlsRefs for any with
   // known dynamic init, or unknown (extern) init.
-  if (op.getTlsModel() == TLS_Model::GeneralDynamic && op.getDynTlsRefs())
+  if (op.getTlsModel() && op.getDynTlsRefs())
     defineGlobalThreadLocalWrapper(op, initAlias, !op.isDeclaration());
 
   assert(!cir::MissingFeatures::opGlobalAnnotations());
@@ -1666,8 +1664,7 @@ void LoweringPreparePass::lowerGetGlobalOp(GetGlobalOp 
op) {
   // get-global operations rewritten to be calls to a wrapper function.  If
   // we're not in a dynamic TLS (or one without the TLS markers), we can leave
   // this one as a get-global and return early.
-  if (globalOp.getTlsModel() != TLS_Model::GeneralDynamic ||
-      !globalOp.getDynTlsRefs())
+  if (!globalOp.getTlsModel() || !globalOp.getDynTlsRefs())
     return;
 
   // If this is a global TLS, we need to replace the call to 'get_global' with 
a
@@ -1792,9 +1789,15 @@ 
LoweringPreparePass::createGlobalThreadLocalGuard(CIRBaseBuilderTy &builder,
   g.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
       builder.getContext(), cir::GlobalLinkageKind::InternalLinkage));
   g.setAlignment(clang::CharUnits::One().getAsAlign().value());
-  // At the moment, we only have implementation for this mode, as it is the
-  // default.  At one point we might need to load this mode from the module.
-  g.setTlsModel(TLS_Model::GeneralDynamic);
+
+  if (auto defTlsModel = mlirModule->getAttrOfType<TLSModelAttr>(
+          cir::CIRDialect::getDefaultTlsModelAttrName())) {
+    g.setTlsModel(defTlsModel.getValue());
+  } else {
+    // Default value, unless overridden in the IR/by the frontend.
+    g.setTlsModel(TLSModel::GeneralDynamic);
+  }
+
   g.setInitialValueAttr(cir::IntAttr::get(guardTy, 0));
   return g;
 }
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 717bf5e2e741e..be9e357fb7eee 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -2777,10 +2777,10 @@ CIRToLLVMGlobalOpLowering::lowerGlobalAttributes(
 }
 
 static mlir::LLVM::ThreadLocalMode
-convertTlsModelAttrToLLVM(TLS_ModelAttr attr) {
+convertTlsModelAttrToLLVM(TLSModelAttr attr) {
   // assert that we can just static-cast these.
 #define CHECK_ENUM(CIR, LLVM_VAL)                                              
\
-  static_assert(static_cast<unsigned>(TLS_Model::CIR) ==                       
\
+  static_assert(static_cast<unsigned>(TLSModel::CIR) ==                        
\
                 static_cast<unsigned>(mlir::LLVM::ThreadLocalMode::LLVM_VAL))
   CHECK_ENUM(GeneralDynamic, GeneralDynamic);
   CHECK_ENUM(LocalDynamic, LocalDynamic);
diff --git a/clang/test/CIR/CodeGen/global-ctor-dtor.cpp 
b/clang/test/CIR/CodeGen/global-ctor-dtor.cpp
index 63f175281a02e..e58261ebf5446 100644
--- a/clang/test/CIR/CodeGen/global-ctor-dtor.cpp
+++ b/clang/test/CIR/CodeGen/global-ctor-dtor.cpp
@@ -36,7 +36,7 @@ void foo4(void) {
 
 // CIR-BEFORE-LPP: cir.func {{.*}} @_Z4foo4v() global_dtor(789)
 
-// CIR-AFTER: module @{{.*}} attributes {cir.global_ctors = 
[#cir.global_ctor<"_Z3foov", 65535>, #cir.global_ctor<"_Z4foo2v", 777>], 
cir.global_dtors = [#cir.global_dtor<"_Z4foo3v", 65535>, 
#cir.global_dtor<"_Z4foo4v", 789>]
+// CIR-AFTER: module @{{.*}} attributes {{{.*}}cir.global_ctors = 
[#cir.global_ctor<"_Z3foov", 65535>, #cir.global_ctor<"_Z4foo2v", 777>], 
cir.global_dtors = [#cir.global_dtor<"_Z4foo3v", 65535>, 
#cir.global_dtor<"_Z4foo4v", 789>]
 
 // LLVM: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, 
ptr, ptr } { i32 65535, ptr @_Z3foov, ptr null }, { i32, ptr, ptr } { i32 777, 
ptr @_Z4foo2v, ptr null }]
 // LLVM: @llvm.global_dtors = appending global [2 x { i32, ptr, ptr }] [{ i32, 
ptr, ptr } { i32 65535, ptr @_Z4foo3v, ptr null }, { i32, ptr, ptr } { i32 789, 
ptr @_Z4foo4v, ptr null }]
diff --git a/clang/test/CIR/CodeGen/tls-model-func-scope.cpp 
b/clang/test/CIR/CodeGen/tls-model-func-scope.cpp
new file mode 100644
index 0000000000000..5567b6fdd9660
--- /dev/null
+++ b/clang/test/CIR/CodeGen/tls-model-func-scope.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -emit-cir -o - | FileCheck 
%s -check-prefix=CIR-GD
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -emit-llvm -fclangir -o - | 
FileCheck %s -check-prefix=LLVM-GD
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -emit-llvm -o - | FileCheck 
%s -check-prefix=LLVM-GD
+
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=global-dynamic 
-emit-cir -o - | FileCheck %s -check-prefix=CIR-GD
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=global-dynamic 
-emit-llvm -fclangir -o - | FileCheck %s -check-prefix=LLVM-GD
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=global-dynamic 
-emit-llvm -o - | FileCheck %s -check-prefix=LLVM-GD
+
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=local-dynamic 
-emit-cir -o - | FileCheck %s -check-prefix=CIR-LD
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=local-dynamic 
-emit-llvm -fclangir -o - | FileCheck %s -check-prefix=LLVM-LD
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=local-dynamic 
-emit-llvm -o - | FileCheck %s -check-prefix=LLVM-LD
+
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=initial-exec 
-emit-cir -o - | FileCheck %s -check-prefix=CIR-IE
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=initial-exec 
-emit-llvm -fclangir -o - | FileCheck %s -check-prefix=LLVM-IE
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=initial-exec 
-emit-llvm -o - | FileCheck %s -check-prefix=LLVM-IE
+
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=local-exec 
-emit-cir -o - | FileCheck %s -check-prefix=CIR-LE
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=local-exec 
-emit-llvm -fclangir -o - | FileCheck %s -check-prefix=LLVM-LE
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=local-exec 
-emit-llvm -o - | FileCheck %s -check-prefix=LLVM-LE
+
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -femulated-tls -emit-cir -o 
- 2>&1 | FileCheck %s -check-prefix=CIR-GD
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -femulated-tls -emit-llvm 
-fclangir -o - 2>&1 | FileCheck %s -check-prefix=LLVM-GD
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -femulated-tls -emit-llvm -o 
- 2>&1 | FileCheck %s -check-prefix=LLVM-GD
+
+int init();
+
+void func() {
+  thread_local int default_tls_mode = init();
+
+  __attribute__((tls_model("initial-exec")))
+  thread_local int override_tls_mode = init();
+}
+// CIR-GD: module {{.*}} attributes
+// CIR-GD-SAME: cir.default.tls_model = #cir.tls_model<tls_dyn>
+// CIR-GD: cir.global "private" internal tls_init_exec dso_local 
@_ZGVZ4funcvE17override_tls_mode = #cir.int<0> : !s8i
+// CIR-GD: cir.global "private" internal tls_dyn dso_local 
@_ZGVZ4funcvE16default_tls_mode = #cir.int<0> : !s8i
+// CIR-GD: cir.global "private" internal tls_init_exec dso_local 
static_local_guard<"_ZGVZ4funcvE17override_tls_mode"> 
@_ZZ4funcvE17override_tls_mode = #cir.int<0> : !s32i
+// CIR-GD: cir.global "private" internal tls_dyn dso_local 
static_local_guard<"_ZGVZ4funcvE16default_tls_mode"> 
@_ZZ4funcvE16default_tls_mode = #cir.int<0> : !s32i
+
+// LLVM-GD-DAG: @_ZGVZ4funcvE17override_tls_mode = internal 
thread_local(initialexec) global i8 0
+// LLVM-GD-DAG: @_ZGVZ4funcvE16default_tls_mode = internal thread_local global 
i8 0
+// LLVM-GD-DAG: @_ZZ4funcvE17override_tls_mode = internal 
thread_local(initialexec) global i32 0
+// LLVM-GD-DAG: @_ZZ4funcvE16default_tls_mode = internal thread_local global 
i32 0
+
+// CIR-LD: module {{.*}} attributes
+// CIR-LD-SAME: cir.default.tls_model = #cir.tls_model<tls_local_dyn>
+// CIR-LD: cir.global "private" internal tls_init_exec dso_local 
@_ZGVZ4funcvE17override_tls_mode = #cir.int<0> : !s8i
+// CIR-LD: cir.global "private" internal tls_local_dyn dso_local 
@_ZGVZ4funcvE16default_tls_mode = #cir.int<0> : !s8i
+// CIR-LD: cir.global "private" internal tls_init_exec dso_local 
static_local_guard<"_ZGVZ4funcvE17override_tls_mode"> 
@_ZZ4funcvE17override_tls_mode = #cir.int<0> : !s32i
+// CIR-LD: cir.global "private" internal tls_local_dyn dso_local 
static_local_guard<"_ZGVZ4funcvE16default_tls_mode"> 
@_ZZ4funcvE16default_tls_mode = #cir.int<0> : !s32i
+
+// LLVM-LD-DAG: @_ZGVZ4funcvE17override_tls_mode = internal 
thread_local(initialexec) global i8 0
+// LLVM-LD-DAG: @_ZGVZ4funcvE16default_tls_mode = internal 
thread_local(localdynamic) global i8 0
+// LLVM-LD-DAG: @_ZZ4funcvE17override_tls_mode = internal 
thread_local(initialexec) global i32 0
+// LLVM-LD-DAG: @_ZZ4funcvE16default_tls_mode = internal 
thread_local(localdynamic) global i32 0
+
+// CIR-IE: module {{.*}} attributes
+// CIR-IE-SAME: cir.default.tls_model = #cir.tls_model<tls_init_exec>
+// CIR-IE: cir.global "private" internal tls_init_exec dso_local 
@_ZGVZ4funcvE17override_tls_mode = #cir.int<0> : !s8i
+// CIR-IE: cir.global "private" internal tls_init_exec dso_local 
@_ZGVZ4funcvE16default_tls_mode = #cir.int<0> : !s8i
+// CIR-IE: cir.global "private" internal tls_init_exec dso_local 
static_local_guard<"_ZGVZ4funcvE17override_tls_mode"> 
@_ZZ4funcvE17override_tls_mode = #cir.int<0> : !s32i
+// CIR-IE: cir.global "private" internal tls_init_exec dso_local 
static_local_guard<"_ZGVZ4funcvE16d...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/215380
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to