https://github.com/erichkeane updated 
https://github.com/llvm/llvm-project/pull/215380

>From b97348e557abdb2a14cb8625237162cdb2b05571 Mon Sep 17 00:00:00 2001
From: erichkeane <[email protected]>
Date: Wed, 5 Aug 2026 14:43:45 -0700
Subject: [PATCH 1/2] [CIR] Implement the 'rest' of the TLS Model types

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.
---
 .../clang/CIR/Dialect/IR/CIRDialect.td        |  1 +
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 18 ++++-
 clang/lib/CIR/CodeGen/CIRGenDeclCXX.cpp       |  3 -
 clang/lib/CIR/CodeGen/CIRGenModule.cpp        | 30 ++++---
 clang/lib/CIR/CodeGen/CIRGenModule.h          |  2 +-
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp       | 26 +++++-
 .../Dialect/Transforms/LoweringPrepare.cpp    | 27 ++++---
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  4 +-
 clang/test/CIR/CodeGen/global-ctor-dtor.cpp   |  2 +-
 .../test/CIR/CodeGen/tls-model-func-scope.cpp | 79 +++++++++++++++++++
 clang/test/CIR/CodeGen/tls-model.cpp          | 58 +++++++-------
 clang/test/CIR/IR/global.cir                  |  8 ++
 clang/test/CIR/IR/invalid-tls.cir             |  9 ++-
 13 files changed, 196 insertions(+), 71 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/tls-model-func-scope.cpp

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<"_ZGVZ4funcvE16default_tls_mode"> 
@_ZZ4funcvE16default_tls_mode = #cir.int<0> : !s32i
+
+// LLVM-IE-DAG: @_ZGVZ4funcvE17override_tls_mode = internal 
thread_local(initialexec) global i8 0
+// LLVM-IE-DAG: @_ZGVZ4funcvE16default_tls_mode = internal 
thread_local(initialexec) global i8 0
+// LLVM-IE-DAG: @_ZZ4funcvE17override_tls_mode = internal 
thread_local(initialexec) global i32 0
+// LLVM-IE-DAG: @_ZZ4funcvE16default_tls_mode = internal 
thread_local(initialexec) global i32 0
+
+// CIR-LE: module {{.*}} attributes
+// CIR-LE-SAME: cir.default.tls_model = #cir.tls_model<tls_local_exec>
+// CIR-LE: cir.global "private" internal tls_init_exec dso_local 
@_ZGVZ4funcvE17override_tls_mode = #cir.int<0> : !s8i
+// CIR-LE: cir.global "private" internal tls_local_exec dso_local 
@_ZGVZ4funcvE16default_tls_mode = #cir.int<0> : !s8i
+// CIR-LE: cir.global "private" internal tls_init_exec dso_local 
static_local_guard<"_ZGVZ4funcvE17override_tls_mode"> 
@_ZZ4funcvE17override_tls_mode = #cir.int<0> : !s32i
+// CIR-LE: cir.global "private" internal tls_local_exec dso_local 
static_local_guard<"_ZGVZ4funcvE16default_tls_mode"> 
@_ZZ4funcvE16default_tls_mode = #cir.int<0> : !s32i
+
+// LLVM-LE-DAG: @_ZGVZ4funcvE17override_tls_mode = internal 
thread_local(initialexec) global i8 0
+// LLVM-LE-DAG: @_ZGVZ4funcvE16default_tls_mode = internal 
thread_local(localexec) global i8 0
+// LLVM-LE-DAG: @_ZZ4funcvE17override_tls_mode = internal 
thread_local(initialexec) global i32 0
+// LLVM-LE-DAG: @_ZZ4funcvE16default_tls_mode = internal 
thread_local(localexec) global i32 0
diff --git a/clang/test/CIR/CodeGen/tls-model.cpp 
b/clang/test/CIR/CodeGen/tls-model.cpp
index 471891a16ca5b..e686faf585036 100644
--- a/clang/test/CIR/CodeGen/tls-model.cpp
+++ b/clang/test/CIR/CodeGen/tls-model.cpp
@@ -46,11 +46,13 @@ struct T thread_local t1;
 // Note that unlike normal C uninitialized global variables,
 // uninitialized TLS variables do NOT have COMMON linkage.
 
+// CIR-GD: module {{.*}} attributes 
+// CIR-GD-SAME: cir.default.tls_model = #cir.tls_model<tls_dyn>
 // CIR-GD-DAG: cir.global external @z1 = #cir.int<0> : !s32i {alignment = 4 : 
i64}
 // CIR-GD-DAG: cir.global external @z2 = #cir.int<0> : !s32i {alignment = 4 : 
i64}
 // CIR-GD-DAG: cir.global external tls_dyn dyn_tls_refs = <"_ZTW1x", "_ZTH1x"> 
@x = #cir.int<0> : !s32i {alignment = 4 : i64}
 // CIR-GD-DAG: cir.global "private" internal tls_dyn dso_local @_ZZ1fvE1y = 
#cir.int<0> : !s32i {alignment = 4 : i64}
-// CIR-GD-DAG: cir.global external tls_init_exec @z = #cir.int<0> : !s32i 
{alignment = 4 : i64}
+// CIR-GD-DAG: cir.global external tls_init_exec dyn_tls_refs = <"_ZTW1z", 
"_ZTH1z"> @z = #cir.int<0> : !s32i {alignment = 4 : i64}
 // CIR-GD-DAG: cir.global external tls_dyn dyn_tls_refs = <"_ZTW2s1", 
"_ZTH2s1"> @s1 = #cir.zero : !rec_S {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
 // CIR-GD-DAG: cir.global external tls_dyn dyn_tls_refs = <"_ZTW2t1", 
"_ZTH2t1"> @t1 = #cir.zero : !rec_T {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
 // CIR-GD-DAG: cir.global internal tls_dyn @__tls_guard = #cir.int<0> : !s8i 
{alignment = 1 : i64}
@@ -64,16 +66,16 @@ struct T thread_local t1;
 // LLVM-GD-DAG: @t1 ={{.*}} thread_local global %struct.T zeroinitializer
 // LLVM-GD-DAG: @__tls_guard = internal thread_local global i8 0
 
+// CIR-LD: module {{.*}} attributes 
+// CIR-LD-SAME: cir.default.tls_model = #cir.tls_model<tls_local_dyn>
 // CIR-LD-DAG: cir.global external @z1 = #cir.int<0> : !s32i {alignment = 4 : 
i64}
 // CIR-LD-DAG: cir.global external @z2 = #cir.int<0> : !s32i {alignment = 4 : 
i64}
-// CIR-LD-DAG: cir.global external tls_local_dyn @x = #cir.int<0> : !s32i 
{alignment = 4 : i64}
+// CIR-LD-DAG: cir.global external tls_local_dyn dyn_tls_refs = <"_ZTW1x", 
"_ZTH1x"> @x = #cir.int<0> : !s32i {alignment = 4 : i64}
 // CIR-LD-DAG: cir.global "private" internal tls_local_dyn dso_local 
@_ZZ1fvE1y = #cir.int<0> : !s32i {alignment = 4 : i64}
-// CIR-LD-DAG: cir.global external tls_init_exec @z = #cir.int<0> : !s32i 
{alignment = 4 : i64}
-// CIR-LD-DAG: cir.global external tls_local_dyn @s1 = #cir.zero : !rec_S 
{alignment = 1 : i64, ast = #cir.var.decl.ast}
-// CIR-LD-DAG: cir.global external tls_local_dyn @t1 = #cir.zero : !rec_T 
{alignment = 1 : i64, ast = #cir.var.decl.ast}
-// FIXME: our lowering for tls only emits the guard for tls_dyn, so this 
doesn't
-// appear.
-// cir.global internal tls_local_dyn @__tls_guard = #cir.int<0> : !s8i 
{alignment = 1 : i64}
+// CIR-LD-DAG: cir.global external tls_init_exec dyn_tls_refs = <"_ZTW1z", 
"_ZTH1z"> @z = #cir.int<0> : !s32i {alignment = 4 : i64}
+// CIR-LD-DAG: cir.global external tls_local_dyn dyn_tls_refs = <"_ZTW2s1", 
"_ZTH2s1"> @s1 = #cir.zero : !rec_S {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
+// CIR-LD-DAG: cir.global external tls_local_dyn dyn_tls_refs = <"_ZTW2t1", 
"_ZTH2t1"> @t1 = #cir.zero : !rec_T {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
+// CIR-LD-DAG: cir.global internal tls_local_dyn @__tls_guard = #cir.int<0> : 
!s8i {alignment = 1 : i64}
 
 // LLVM-LD-DAG: @z1 ={{.*}} global i32 0
 // LLVM-LD-DAG: @z2 ={{.*}} global i32 0
@@ -82,20 +84,18 @@ struct T thread_local t1;
 // LLVM-LD-DAG: @z ={{.*}} thread_local(initialexec) global i32 0
 // LLVM-LD-DAG: @s1 ={{.*}} thread_local(localdynamic) global %struct.S 
zeroinitializer
 // LLVM-LD-DAG: @t1 ={{.*}} thread_local(localdynamic) global %struct.T 
zeroinitializer
-// FIXME: our lowering for tls only emits the guard for tls_dyn, so this 
doesn't
-// appear.
-// @__tls_guard = internal thread_local(localdynamic) global i8 0
+// LLVM-LD-DAG: @__tls_guard = internal thread_local(localdynamic) global i8 0
 
+// CIR-IE: module {{.*}} attributes 
+// CIR-IE-SAME: cir.default.tls_model = #cir.tls_model<tls_init_exec>
 // CIR-IE-DAG: cir.global external @z1 = #cir.int<0> : !s32i {alignment = 4 : 
i64}
 // CIR-IE-DAG: cir.global external @z2 = #cir.int<0> : !s32i {alignment = 4 : 
i64}
-// CIR-IE-DAG: cir.global external tls_init_exec @x = #cir.int<0> : !s32i 
{alignment = 4 : i64}
+// CIR-IE-DAG: cir.global external tls_init_exec dyn_tls_refs = <"_ZTW1x", 
"_ZTH1x"> @x = #cir.int<0> : !s32i {alignment = 4 : i64}
 // CIR-IE-DAG: cir.global "private" internal tls_init_exec dso_local 
@_ZZ1fvE1y = #cir.int<0> : !s32i {alignment = 4 : i64}
-// CIR-IE-DAG: cir.global external tls_init_exec @z = #cir.int<0> : !s32i 
{alignment = 4 : i64}
-// CIR-IE-DAG: cir.global external tls_init_exec @s1 = #cir.zero : !rec_S 
{alignment = 1 : i64, ast = #cir.var.decl.ast}
-// CIR-IE-DAG: cir.global external tls_init_exec @t1 = #cir.zero : !rec_T 
{alignment = 1 : i64, ast = #cir.var.decl.ast}
-// FIXME: our lowering for tls only emits the guard for tls_dyn, so this 
doesn't
-// appear.
-// cir.global internal tls_init_exec @__tls_guard = #cir.int<0> : !s8i 
{alignment = 1 : i64}
+// CIR-IE-DAG: cir.global external tls_init_exec dyn_tls_refs = <"_ZTW1z", 
"_ZTH1z"> @z = #cir.int<0> : !s32i {alignment = 4 : i64}
+// CIR-IE-DAG: cir.global external tls_init_exec dyn_tls_refs = <"_ZTW2s1", 
"_ZTH2s1"> @s1 = #cir.zero : !rec_S {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
+// CIR-IE-DAG: cir.global external tls_init_exec dyn_tls_refs = <"_ZTW2t1", 
"_ZTH2t1"> @t1 = #cir.zero : !rec_T {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
+// CIR-IE-DAG: cir.global internal tls_init_exec @__tls_guard = #cir.int<0> : 
!s8i {alignment = 1 : i64}
 
 // LLVM-IE-DAG: @z1 ={{.*}} global i32 0
 // LLVM-IE-DAG: @z2 ={{.*}} global i32 0
@@ -104,20 +104,18 @@ struct T thread_local t1;
 // LLVM-IE-DAG: @z ={{.*}} thread_local(initialexec) global i32 0
 // LLVM-IE-DAG: @s1 ={{.*}} thread_local(initialexec) global %struct.S 
zeroinitializer
 // LLVM-IE-DAG: @t1 ={{.*}} thread_local(initialexec) global %struct.T 
zeroinitializer
-// FIXME: our lowering for tls only emits the guard for tls_dyn, so this 
doesn't
-// appear.
-// @__tls_guard = internal thread_local(initialexec) global i8 0
+// LLVM-IE-DAG: @__tls_guard = internal thread_local(initialexec) global i8 0
 
+// CIR-LE: module {{.*}} attributes 
+// CIR-LE-SAME: cir.default.tls_model = #cir.tls_model<tls_local_exec>
 // CIR-LE-DAG: cir.global external @z1 = #cir.int<0> : !s32i {alignment = 4 : 
i64}
 // CIR-LE-DAG: cir.global external @z2 = #cir.int<0> : !s32i {alignment = 4 : 
i64}
-// CIR-LE-DAG: cir.global external tls_local_exec @x = #cir.int<0> : !s32i 
{alignment = 4 : i64}
+// CIR-LE-DAG: cir.global external tls_local_exec dyn_tls_refs = <"_ZTW1x", 
"_ZTH1x"> @x = #cir.int<0> : !s32i {alignment = 4 : i64}
 // CIR-LE-DAG: cir.global "private" internal tls_local_exec dso_local 
@_ZZ1fvE1y = #cir.int<0> : !s32i {alignment = 4 : i64}
-// CIR-LE-DAG: cir.global external tls_init_exec @z = #cir.int<0> : !s32i 
{alignment = 4 : i64}
-// CIR-LE-DAG: cir.global external tls_local_exec @s1 = #cir.zero : !rec_S 
{alignment = 1 : i64, ast = #cir.var.decl.ast}
-// CIR-LE-DAG: cir.global external tls_local_exec @t1 = #cir.zero : !rec_T 
{alignment = 1 : i64, ast = #cir.var.decl.ast}
-// FIXME: our lowering for tls only emits the guard for tls_dyn, so this 
doesn't
-// appear.
-// cir.global internal tls_local_exec @__tls_guard = #cir.int<0> : !s8i 
{alignment = 1 : i64}
+// CIR-LE-DAG: cir.global external tls_init_exec dyn_tls_refs = <"_ZTW1z", 
"_ZTH1z"> @z = #cir.int<0> : !s32i {alignment = 4 : i64}
+// CIR-LE-DAG: cir.global external tls_local_exec dyn_tls_refs = <"_ZTW2s1", 
"_ZTH2s1"> @s1 = #cir.zero : !rec_S {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
+// CIR-LE-DAG: cir.global external tls_local_exec dyn_tls_refs = <"_ZTW2t1", 
"_ZTH2t1"> @t1 = #cir.zero : !rec_T {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
+// CIR-LE-DAG: cir.global internal tls_local_exec @__tls_guard = #cir.int<0> : 
!s8i {alignment = 1 : i64}
 
 // LLVM-LE-DAG: @z1 ={{.*}} global i32 0
 // LLVM-LE-DAG: @z2 ={{.*}} global i32 0
@@ -126,6 +124,4 @@ struct T thread_local t1;
 // LLVM-LE-DAG: @z ={{.*}} thread_local(initialexec) global i32 0
 // LLVM-LE-DAG: @s1 ={{.*}} thread_local(localexec) global %struct.S 
zeroinitializer
 // LLVM-LE-DAG: @t1 ={{.*}} thread_local(localexec) global %struct.T 
zeroinitializer
-// FIXME: our lowering for tls only emits the guard for tls_dyn, so this 
doesn't
-// appear.
-// @__tls_guard = internal thread_local(localexec) global i8 0
+// LLVM-LE-DAG: @__tls_guard = internal thread_local(localexec) global i8 0
diff --git a/clang/test/CIR/IR/global.cir b/clang/test/CIR/IR/global.cir
index fe3a0b95c65f3..3e78fa627b4aa 100644
--- a/clang/test/CIR/IR/global.cir
+++ b/clang/test/CIR/IR/global.cir
@@ -49,6 +49,10 @@ module attributes {cir.triple = "x86_64-unknown-linux-gnu"} {
   cir.global external @fp = #cir.ptr<null> : !cir.ptr<!cir.func<()>>
   cir.global external @fpii = #cir.ptr<null> : !cir.ptr<!cir.func<(!s32i) -> 
!s32i>>
   cir.global external @fpvar = #cir.ptr<null> : !cir.ptr<!cir.func<(!s32i, 
...)>>
+  cir.global external tls_dyn @tls1 = #cir.int<0> : !s8i
+  cir.global external tls_local_dyn @tls2 = #cir.int<0> : !s8i
+  cir.global external tls_init_exec @tls3 = #cir.int<0> : !s8i
+  cir.global external tls_local_exec @tls4 = #cir.int<0> : !s8i
 }
 
 // CHECK: cir.global external @c = #cir.int<0> : !s8i
@@ -87,3 +91,7 @@ module attributes {cir.triple = "x86_64-unknown-linux-gnu"} {
 // CHECK: cir.global external @fp = #cir.ptr<null> : !cir.ptr<!cir.func<()>>
 // CHECK: cir.global external @fpii = #cir.ptr<null> : 
!cir.ptr<!cir.func<(!s32i) -> !s32i>>
 // CHECK: cir.global external @fpvar = #cir.ptr<null> : 
!cir.ptr<!cir.func<(!s32i, ...)>>
+// CHECK: cir.global external tls_dyn @tls1 = #cir.int<0> : !s8i
+// CHECK: cir.global external tls_local_dyn @tls2 = #cir.int<0> : !s8i
+// CHECK: cir.global external tls_init_exec @tls3 = #cir.int<0> : !s8i
+// CHECK: cir.global external tls_local_exec @tls4 = #cir.int<0> : !s8i
diff --git a/clang/test/CIR/IR/invalid-tls.cir 
b/clang/test/CIR/IR/invalid-tls.cir
index e33b7070eb790..de10382b9ae1e 100644
--- a/clang/test/CIR/IR/invalid-tls.cir
+++ b/clang/test/CIR/IR/invalid-tls.cir
@@ -25,7 +25,10 @@ cir.global "private" internal tls_dyn dyn_tls_refs = 
<"asdf", "asdf", "asdf"> st
 !s32i = !cir.int<s, 32>
 
 module {
-  // expected-error@+1{{'dyn_tls_refs' only valid for dynamic tls}}
-cir.global "private" internal tls_local_dyn dyn_tls_refs = <"asdf", "asdf", 
"asdf"> @_ZZ1fvE1y : !s32i
+  // FIXME(cir) Parsing continues on when tls doesn't get recognized, and
+  // unfortunately Address space is the only thing that comes next. We should
+  // probably do a better job having address-space give up if we care enough 
here.
+  // expected-error@+2{{failed to parse Address Space Value for GlobalOp}}
+  // expected-error@+1{{custom op 'cir.global' unknown address space specifier 
'invalid_tls_dyn'}}
+cir.global "private" internal invalid_tls_dyn dyn_tls_refs = <"asdf", "asdf", 
"asdf"> @_ZZ1fvE1y : !s32i
 }
-

>From 6e091d71924ba0d4d6c3e932405c4c8ded1169bd Mon Sep 17 00:00:00 2001
From: erichkeane <[email protected]>
Date: Mon, 10 Aug 2026 16:56:07 -0700
Subject: [PATCH 2/2] Remove custom printer, replace with tls_model = <tls_dyn>
 type printing

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  |  2 +-
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp       | 24 ----------
 clang/test/CIR/CodeGen/global-temp-dtor.cpp   | 16 +++----
 .../test/CIR/CodeGen/global-tls-dyn-init.cpp  | 18 +++----
 .../CIR/CodeGen/global-tls-simple-init.cpp    | 28 +++++------
 .../test/CIR/CodeGen/global-tls-templates.cpp | 12 ++---
 .../test/CIR/CodeGen/thread-local-in-func.cpp | 26 +++++-----
 .../test/CIR/CodeGen/tls-model-func-scope.cpp | 32 ++++++-------
 clang/test/CIR/CodeGen/tls-model.cpp          | 48 +++++++++----------
 clang/test/CIR/CodeGen/tls.c                  |  4 +-
 clang/test/CIR/IR/global.cir                  | 16 +++----
 clang/test/CIR/IR/invalid-tls.cir             | 11 ++---
 12 files changed, 105 insertions(+), 132 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index b17f9b3e22f88..d427fcda1445f 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -3381,7 +3381,7 @@ def CIR_GlobalOp : CIR_Op<"global", [
     (`constant` $constant^)?
     $linkage
     (`comdat` $comdat^)?
-    (` ` custom<TLSModel>($tls_model)^ )?
+    (`tls_model` `=` $tls_model^)?
     (`dyn_tls_refs` `=` $dyn_tls_refs^)?
     (`dso_local` $dso_local^)?
     (`static_local_guard` `` $static_local_guard^)?
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index cfea69146987e..93bf1233f156c 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -288,30 +288,6 @@ 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
 
//===----------------------------------------------------------------------===//
diff --git a/clang/test/CIR/CodeGen/global-temp-dtor.cpp 
b/clang/test/CIR/CodeGen/global-temp-dtor.cpp
index a59f7d8e72c40..34782004b5d8c 100644
--- a/clang/test/CIR/CodeGen/global-temp-dtor.cpp
+++ b/clang/test/CIR/CodeGen/global-temp-dtor.cpp
@@ -47,7 +47,7 @@ thread_local const NonTrivialArr &thread_arr_ref = 
NonTrivialArr{};
 // CIR:   cir.call @__cxa_atexit
 // CIR: cir.global "private" internal @_ZGR10static_ref_ = #cir.zero : 
!rec_NonTrivial
 
-// CIR-BEFORE: cir.global external tls_dyn dyn_tls_refs = <"_ZTW10thread_ref", 
"_ZTH10thread_ref"> @thread_ref = ctor : !cir.ptr<!rec_NonTrivial> {
+// CIR-BEFORE: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW10thread_ref", "_ZTH10thread_ref"> @thread_ref = ctor : 
!cir.ptr<!rec_NonTrivial> {
 // CIR-BEFORE:   %[[THREAD_REF:.*]] = cir.get_global thread_local @thread_ref
 // CIR-BEFORE:   %[[REF_TEMP:.*]] = cir.get_global @_ZGR10thread_ref_
 // CIR-BEFORE:   cir.call @_ZN10NonTrivialC1Ev(%[[REF_TEMP]])
@@ -56,9 +56,9 @@ thread_local const NonTrivialArr &thread_arr_ref = 
NonTrivialArr{};
 // CIR-BEFORE:   %[[REF_TEMP_DTOR:.*]] = cir.get_global @_ZGR10thread_ref_
 // CIR-BEFORE:   cir.call @_ZN10NonTrivialD1Ev(%[[REF_TEMP_DTOR]])
 // CIR-BEFORE: }
-// CIR-BEFORE: cir.global "private" internal tls_dyn @_ZGR10thread_ref_ = 
#cir.zero : !rec_NonTrivial
+// CIR-BEFORE: cir.global "private" internal tls_model = <tls_dyn> 
@_ZGR10thread_ref_ = #cir.zero : !rec_NonTrivial
 
-// CIR: cir.global external tls_dyn dyn_tls_refs = <"_ZTW10thread_ref", 
"_ZTH10thread_ref"> @thread_ref = #cir.ptr<null> : !cir.ptr<!rec_NonTrivial>
+// CIR: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW10thread_ref", "_ZTH10thread_ref"> @thread_ref = #cir.ptr<null> : 
!cir.ptr<!rec_NonTrivial>
 // CIR: cir.func internal private @__cxx_global_var_init.1()
 // CIR:   cir.get_global thread_local @thread_ref
 // CIR:   cir.get_global @_ZGR10thread_ref_
@@ -68,7 +68,7 @@ thread_local const NonTrivialArr &thread_arr_ref = 
NonTrivialArr{};
 // CIR:   cir.get_global @_ZN10NonTrivialD1Ev
 // CIR:   cir.get_global @__dso_handle
 // CIR:   cir.call @__cxa_thread_atexit
-// CIR: cir.global "private" internal tls_dyn @_ZGR10thread_ref_ = #cir.zero : 
!rec_NonTrivial
+// CIR: cir.global "private" internal tls_model = <tls_dyn> @_ZGR10thread_ref_ 
= #cir.zero : !rec_NonTrivial
 
 // CIR-BEFORE: cir.global external @static_arr_ref = ctor : 
!cir.ptr<!cir.array<!rec_NonTrivial x 2>> {
 // CIR-BEFORE:   %[[ARRAY_INIT_TEMP:.*]] = cir.alloca {{.*}}"arrayinit.temp"
@@ -108,7 +108,7 @@ thread_local const NonTrivialArr &thread_arr_ref = 
NonTrivialArr{};
 // CIR:   cir.call @__cxa_atexit
 // CIR: cir.global "private" internal @_ZGR14static_arr_ref_ = #cir.zero : 
!cir.array<!rec_NonTrivial x 2>
 
-// CIR-BEFORE: cir.global external tls_dyn dyn_tls_refs = 
<"_ZTW14thread_arr_ref", "_ZTH14thread_arr_ref"> @thread_arr_ref = ctor : 
!cir.ptr<!cir.array<!rec_NonTrivial x 2>> {
+// CIR-BEFORE: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW14thread_arr_ref", "_ZTH14thread_arr_ref"> @thread_arr_ref = ctor : 
!cir.ptr<!cir.array<!rec_NonTrivial x 2>> {
 // CIR-BEFORE:   %[[ARRAY_INIT_TEMP:.*]] = cir.alloca {{.*}}"arrayinit.temp"
 // CIR-BEFORE:   %[[THREAD_ARR_REF:.*]] = cir.get_global thread_local 
@thread_arr_ref
 // CIR-BEFORE:   %[[THREAD_ARR_REF_TEMP:.*]] = cir.get_global 
@_ZGR14thread_arr_ref_
@@ -129,9 +129,9 @@ thread_local const NonTrivialArr &thread_arr_ref = 
NonTrivialArr{};
 // CIR-BEFORE:     cir.call @_ZN10NonTrivialD1Ev(%[[ELEMENT]])
 // CIR-BEFORE:   }
 // CIR-BEFORE: }
-// CIR-BEFORE: cir.global "private" internal tls_dyn @_ZGR14thread_arr_ref_ = 
#cir.zero : !cir.array<!rec_NonTrivial x 2>
+// CIR-BEFORE: cir.global "private" internal tls_model = <tls_dyn> 
@_ZGR14thread_arr_ref_ = #cir.zero : !cir.array<!rec_NonTrivial x 2>
 
-// CIR: cir.global external tls_dyn dyn_tls_refs = <"_ZTW14thread_arr_ref", 
"_ZTH14thread_arr_ref"> @thread_arr_ref = #cir.ptr<null> : 
!cir.ptr<!cir.array<!rec_NonTrivial x 2>>
+// CIR: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW14thread_arr_ref", "_ZTH14thread_arr_ref"> @thread_arr_ref = 
#cir.ptr<null> : !cir.ptr<!cir.array<!rec_NonTrivial x 2>>
 // CIR: cir.func internal private @__cxx_global_array_dtor.1(
 // CIR:   cir.do {
 // CIR:     cir.call @_ZN10NonTrivialD1Ev
@@ -144,7 +144,7 @@ thread_local const NonTrivialArr &thread_arr_ref = 
NonTrivialArr{};
 // CIR:   cir.get_global @__cxx_global_array_dtor.1
 // CIR:   cir.get_global @__dso_handle
 // CIR:   cir.call @__cxa_thread_atexit
-// CIR: cir.global "private" internal tls_dyn @_ZGR14thread_arr_ref_ = 
#cir.zero : !cir.array<!rec_NonTrivial x 2>
+// CIR: cir.global "private" internal tls_model = <tls_dyn> 
@_ZGR14thread_arr_ref_ = #cir.zero : !cir.array<!rec_NonTrivial x 2>
 
 // LLVM-DAG: @static_ref = global ptr null
 // LLVM-DAG: @_ZGR10static_ref_ = internal global %struct.NonTrivial 
zeroinitializer
diff --git a/clang/test/CIR/CodeGen/global-tls-dyn-init.cpp 
b/clang/test/CIR/CodeGen/global-tls-dyn-init.cpp
index 68973223eb303..e9905037bdf0d 100644
--- a/clang/test/CIR/CodeGen/global-tls-dyn-init.cpp
+++ b/clang/test/CIR/CodeGen/global-tls-dyn-init.cpp
@@ -23,7 +23,7 @@ struct CtorDtor {
 // LLVM-BOTH-DAG: @_ZTH6tls_cd = alias void (), ptr @__tls_init
 
 // Wrappers & aliases.
-// CIR:       cir.global internal tls_dyn @__tls_guard = #cir.int<0> : !s8i 
{alignment = 1 : i64}
+// CIR:       cir.global internal tls_model = <tls_dyn> @__tls_guard = 
#cir.int<0> : !s8i {alignment = 1 : i64}
 // CIR-LABEL: cir.func comdat weak_odr private hidden 
@_ZTW19tls_cd_dyn_not_used() -> !cir.ptr<!rec_CtorDtor> {
 // CIR: cir.call @_ZTH19tls_cd_dyn_not_used() : () -> ()
 // CIR: %[[GET_GLOB:.*]] = cir.get_global thread_local @tls_cd_dyn_not_used : 
!cir.ptr<!rec_CtorDtor>
@@ -100,11 +100,11 @@ struct CtorDtor {
 // LLVM:   call void @[[TLS_CD_DYN_NOT_USED_INIT:.*]]()
 
 thread_local CtorDtor tls_cd = 5;
-// CIR-BEFORE-LPP: cir.global external tls_dyn dyn_tls_refs = <"_ZTW6tls_cd", 
"_ZTH6tls_cd"> @tls_cd = #cir.const_record<{#cir.int<5> : !s32i}> : 
!rec_CtorDtor dtor {
+// CIR-BEFORE-LPP: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW6tls_cd", "_ZTH6tls_cd"> @tls_cd = #cir.const_record<{#cir.int<5> : 
!s32i}> : !rec_CtorDtor dtor {
 // CIR-BEFORE-LPP:   %[[GET_GLOB:.*]] = cir.get_global thread_local @tls_cd : 
!cir.ptr<!rec_CtorDtor>
 // CIR-BEFORE-LPP:   cir.call @_ZN8CtorDtorD1Ev(%[[GET_GLOB]]) : 
(!cir.ptr<!rec_CtorDtor>) -> ()
 // CIR-BEFORE-LPP: }
-// CIR: cir.global external tls_dyn dyn_tls_refs = <"_ZTW6tls_cd", 
"_ZTH6tls_cd"> @tls_cd = #cir.const_record<{#cir.int<5> : !s32i}> : 
!rec_CtorDtor
+// CIR: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW6tls_cd", "_ZTH6tls_cd"> @tls_cd = #cir.const_record<{#cir.int<5> : 
!s32i}> : !rec_CtorDtor
 // CIR: cir.func internal private @[[TLS_CD_INIT]]() {
 // CIR:   %[[GET_GLOB:.*]] = cir.get_global thread_local @tls_cd : 
!cir.ptr<!rec_CtorDtor>
 // CIR:   %[[GET_DTOR:.*]] = cir.get_global @_ZN8CtorDtorD1Ev : 
!cir.ptr<!cir.func<(!cir.ptr<!rec_CtorDtor>)>>
@@ -122,7 +122,7 @@ thread_local CtorDtor tls_cd = 5;
 // LLVM-BOTH:   ret void
 
 thread_local CtorDtor tls_cd_dyn = get_i();
-// CIR-BEFORE-LPP:  cir.global external tls_dyn dyn_tls_refs = 
<"_ZTW10tls_cd_dyn", "_ZTH10tls_cd_dyn"> @tls_cd_dyn = ctor : !rec_CtorDtor {
+// CIR-BEFORE-LPP:  cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW10tls_cd_dyn", "_ZTH10tls_cd_dyn"> @tls_cd_dyn = ctor : !rec_CtorDtor {
 // CIR-BEFORE-LPP:    %[[GET_GLOB:.*]] = cir.get_global thread_local 
@tls_cd_dyn : !cir.ptr<!rec_CtorDtor>
 // CIR-BEFORE-LPP:    %[[CALL:.*]] = cir.call @_Z5get_iv() : () -> (!s32i 
{llvm.noundef})
 // CIR-BEFORE-LPP:    cir.call @_ZN8CtorDtorC1Ei(%[[GET_GLOB]], %[[CALL]]) : 
(!cir.ptr<!rec_CtorDtor>
@@ -130,7 +130,7 @@ thread_local CtorDtor tls_cd_dyn = get_i();
 // CIR-BEFORE-LPP:    %[[GET_GLOB:.*]] = cir.get_global thread_local 
@tls_cd_dyn : !cir.ptr<!rec_CtorDtor>
 // CIR-BEFORE-LPP:    cir.call @_ZN8CtorDtorD1Ev(%[[GET_GLOB]]) : 
(!cir.ptr<!rec_CtorDtor>) -> ()
 // CIR-BEFORE-LPP:  }
-// CIR: cir.global external tls_dyn dyn_tls_refs = <"_ZTW10tls_cd_dyn", 
"_ZTH10tls_cd_dyn"> @tls_cd_dyn = #cir.zero : !rec_CtorDtor
+// CIR: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW10tls_cd_dyn", "_ZTH10tls_cd_dyn"> @tls_cd_dyn = #cir.zero : !rec_CtorDtor
 // CIR: cir.func internal private @[[TLS_CD_DYN_INIT]]() {
 // CIR:   %[[GET_GLOB:.*]] = cir.get_global thread_local @tls_cd_dyn : 
!cir.ptr<!rec_CtorDtor>
 // CIR:   %[[CALL:.*]] = cir.call @_Z5get_iv() : () -> (!s32i {llvm.noundef})
@@ -155,12 +155,12 @@ thread_local CtorDtor tls_cd_dyn = get_i();
 // LLVM-BOTH:   ret void
 
 thread_local CtorDtor &tls_cd_ref = tls_cd_dyn;
-// CIR-BEFORE-LPP: cir.global external tls_dyn dyn_tls_refs = 
<"_ZTW10tls_cd_ref", "_ZTH10tls_cd_ref"> @tls_cd_ref = ctor : 
!cir.ptr<!rec_CtorDtor> {
+// CIR-BEFORE-LPP: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW10tls_cd_ref", "_ZTH10tls_cd_ref"> @tls_cd_ref = ctor : 
!cir.ptr<!rec_CtorDtor> {
 // CIR-BEFORE-LPP:   %[[GET_GLOB:.*]] = cir.get_global thread_local 
@tls_cd_ref : !cir.ptr<!cir.ptr<!rec_CtorDtor>>
 // CIR-BEFORE-LPP:   %[[CALL:.*]] = cir.get_global thread_local @tls_cd_dyn : 
!cir.ptr<!rec_CtorDtor>
 // CIR-BEFORE-LPP:   cir.store {{.*}}%[[CALL]], %[[GET_GLOB]] : 
!cir.ptr<!rec_CtorDtor>, !cir.ptr<!cir.ptr<!rec_CtorDtor>>
 // CIR-BEFORE-LPP: }
-// CIR: cir.global external tls_dyn dyn_tls_refs = <"_ZTW10tls_cd_ref", 
"_ZTH10tls_cd_ref"> @tls_cd_ref = #cir.ptr<null> : !cir.ptr<!rec_CtorDtor>
+// CIR: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW10tls_cd_ref", "_ZTH10tls_cd_ref"> @tls_cd_ref = #cir.ptr<null> : 
!cir.ptr<!rec_CtorDtor>
 // CIR: cir.func internal private @[[TLS_CD_REF_INIT]]() {
 // CIR:   %[[GET_GLOB:.*]] = cir.get_global thread_local @tls_cd_ref : 
!cir.ptr<!cir.ptr<!rec_CtorDtor>>
 // CIR:   %[[GET_DYN:.*]] = cir.call @_ZTW10tls_cd_dyn() : () -> 
!cir.ptr<!rec_CtorDtor>
@@ -182,7 +182,7 @@ thread_local CtorDtor &tls_cd_ref = tls_cd_dyn;
 // OGCG: }
 
 thread_local CtorDtor tls_cd_dyn_not_used = get_i();
-// CIR-BEFORE-LPP: cir.global external tls_dyn dyn_tls_refs = 
<"_ZTW19tls_cd_dyn_not_used", "_ZTH19tls_cd_dyn_not_used"> @tls_cd_dyn_not_used 
= ctor : !rec_CtorDtor {
+// CIR-BEFORE-LPP: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW19tls_cd_dyn_not_used", "_ZTH19tls_cd_dyn_not_used"> @tls_cd_dyn_not_used 
= ctor : !rec_CtorDtor {
 // CIR-BEFORE-LPP:   %[[GET_GLOB:.*]] = cir.get_global thread_local 
@tls_cd_dyn_not_used : !cir.ptr<!rec_CtorDtor>
 // CIR-BEFORE-LPP:   %[[CALL:.*]] = cir.call @_Z5get_iv() : () -> (!s32i 
{llvm.noundef})
 // CIR-BEFORE-LPP:   cir.call @_ZN8CtorDtorC1Ei(%[[GET_GLOB]], %[[CALL]])
@@ -190,7 +190,7 @@ thread_local CtorDtor tls_cd_dyn_not_used = get_i();
 // CIR-BEFORE-LPP:   %[[GET_GLOB:.*]] = cir.get_global thread_local 
@tls_cd_dyn_not_used : !cir.ptr<!rec_CtorDtor>
 // CIR-BEFORE-LPP:   cir.call @_ZN8CtorDtorD1Ev(%[[GET_GLOB]]) : 
(!cir.ptr<!rec_CtorDtor>) -> ()
 // CIR-BEFORE-LPP: }
-// CIR: cir.global external tls_dyn dyn_tls_refs = 
<"_ZTW19tls_cd_dyn_not_used", "_ZTH19tls_cd_dyn_not_used"> @tls_cd_dyn_not_used 
= #cir.zero : !rec_CtorDtor
+// CIR: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW19tls_cd_dyn_not_used", "_ZTH19tls_cd_dyn_not_used"> @tls_cd_dyn_not_used 
= #cir.zero : !rec_CtorDtor
 // CIR: cir.func internal private @[[TLS_CD_DYN_NOT_USED_INIT]]() {
 // CIR:   %[[GET_GLOB:.*]] = cir.get_global thread_local @tls_cd_dyn_not_used 
: !cir.ptr<!rec_CtorDtor>
 // CIR:   %[[CALL:.*]] = cir.call @_Z5get_iv() : () -> (!s32i {llvm.noundef})
diff --git a/clang/test/CIR/CodeGen/global-tls-simple-init.cpp 
b/clang/test/CIR/CodeGen/global-tls-simple-init.cpp
index 4d480bfa64f5b..688aa6a49af66 100644
--- a/clang/test/CIR/CodeGen/global-tls-simple-init.cpp
+++ b/clang/test/CIR/CodeGen/global-tls-simple-init.cpp
@@ -140,16 +140,16 @@ struct CtorDtor {
 
 
 thread_local int tls_int = 5;
-// CIR-BEFORE-LPP: cir.global external tls_dyn dyn_tls_refs = <"_ZTW7tls_int", 
"_ZTH7tls_int"> @tls_int = #cir.int<5> : !s32i
-// CIR: cir.global external tls_dyn dyn_tls_refs = <"_ZTW7tls_int", 
"_ZTH7tls_int"> @tls_int = #cir.int<5> : !s32i
+// CIR-BEFORE-LPP: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW7tls_int", "_ZTH7tls_int"> @tls_int = #cir.int<5> : !s32i
+// CIR: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW7tls_int", "_ZTH7tls_int"> @tls_int = #cir.int<5> : !s32i
 
 thread_local int tls_int_dyn = get_i();
-// CIR-BEFORE-LPP: cir.global external tls_dyn dyn_tls_refs = 
<"_ZTW11tls_int_dyn", "_ZTH11tls_int_dyn"> @tls_int_dyn = ctor : !s32i {
+// CIR-BEFORE-LPP: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW11tls_int_dyn", "_ZTH11tls_int_dyn"> @tls_int_dyn = ctor : !s32i {
 // CIR-BEFORE-LPP:   %[[GET_GLOB:.*]] = cir.get_global thread_local 
@tls_int_dyn : !cir.ptr<!s32i>
 // CIR-BEFORE-LPP:   %[[CALL:.*]] = cir.call @_Z5get_iv() : () -> (!s32i 
{llvm.noundef})
 // CIR-BEFORE-LPP:   cir.store {{.*}}%[[CALL]], %[[GET_GLOB]] : !s32i, 
!cir.ptr<!s32i>
 // CIR-BEFORE-LPP: }
-// CIR: cir.global external tls_dyn dyn_tls_refs = <"_ZTW11tls_int_dyn", 
"_ZTH11tls_int_dyn"> @tls_int_dyn = #cir.int<0> : !s32i 
+// CIR: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW11tls_int_dyn", "_ZTH11tls_int_dyn"> @tls_int_dyn = #cir.int<0> : !s32i 
 // CIR: cir.func internal private @[[TLS_INT_DYN_INIT]]() {
 // CIR:   %[[GET_GLOB:.*]] = cir.get_global thread_local @tls_int_dyn : 
!cir.ptr<!s32i>
 // CIR:   %[[CALL:.*]] = cir.call @_Z5get_iv() : () -> (!s32i {llvm.noundef})
@@ -164,12 +164,12 @@ thread_local int tls_int_dyn = get_i();
 // LLVM-BOTH:   ret void
 
 thread_local int &tls_int_ref = tls_int_dyn;
-// CIR-BEFORE-LPP: cir.global external tls_dyn dyn_tls_refs = 
<"_ZTW11tls_int_ref", "_ZTH11tls_int_ref"> @tls_int_ref = ctor : 
!cir.ptr<!s32i> {
+// CIR-BEFORE-LPP: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW11tls_int_ref", "_ZTH11tls_int_ref"> @tls_int_ref = ctor : 
!cir.ptr<!s32i> {
 // CIR-BEFORE-LPP:   %[[GET_GLOB:.*]] = cir.get_global thread_local 
@tls_int_ref : !cir.ptr<!cir.ptr<!s32i>>
 // CIR-BEFORE-LPP:   %[[GET_OTHER:.*]] = cir.get_global thread_local 
@tls_int_dyn : !cir.ptr<!s32i>
 // CIR-BEFORE-LPP:   cir.store {{.*}}%[[GET_OTHER]], %[[GET_GLOB]] : 
!cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
 // CIR-BEFORE-LPP: }
-// CIR: cir.global external tls_dyn dyn_tls_refs = <"_ZTW11tls_int_ref", 
"_ZTH11tls_int_ref"> @tls_int_ref = #cir.ptr<null> : !cir.ptr<!s32i>
+// CIR: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW11tls_int_ref", "_ZTH11tls_int_ref"> @tls_int_ref = #cir.ptr<null> : 
!cir.ptr<!s32i>
 // CIR: cir.func internal private @[[TLS_INT_REF_INIT]]() {
 // CIR:   %[[GET_GLOB:.*]] = cir.get_global thread_local @tls_int_ref : 
!cir.ptr<!cir.ptr<!s32i>>
 // CIR:   %[[GET_REF:.*]] = cir.call @_ZTW11tls_int_dyn() : () -> 
!cir.ptr<!s32i>
@@ -189,7 +189,7 @@ thread_local int &tls_int_ref = tls_int_dyn;
 // OGCG:   ret ptr %[[GET_GLOB]]
 
 thread_local int tls_int_self_init = tls_int_self_init + get_i();
-// CIR-BEFORE-LPP:  cir.global external tls_dyn dyn_tls_refs = 
<"_ZTW17tls_int_self_init", "_ZTH17tls_int_self_init"> @tls_int_self_init = 
ctor : !s32i {
+// CIR-BEFORE-LPP:  cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW17tls_int_self_init", "_ZTH17tls_int_self_init"> @tls_int_self_init = 
ctor : !s32i {
 // CIR-BEFORE-LPP:    %[[GET_GLOB:.*]] = cir.get_global thread_local 
@tls_int_self_init : !cir.ptr<!s32i>
 // CIR-BEFORE-LPP:    %[[GET_SELF:.*]] = cir.get_global thread_local 
@tls_int_self_init : !cir.ptr<!s32i>
 // CIR-BEFORE-LPP:    %[[LOAD_SELF:.*]] = cir.load {{.*}}%[[GET_SELF]] : 
!cir.ptr<!s32i>, !s32i
@@ -197,7 +197,7 @@ thread_local int tls_int_self_init = tls_int_self_init + 
get_i();
 // CIR-BEFORE-LPP:    %[[ADD:.*]] = cir.add nsw %[[LOAD_SELF]], %[[CALL]] : 
!s32i
 // CIR-BEFORE-LPP:    cir.store {{.*}}%[[ADD]], %[[GET_GLOB]] : !s32i, 
!cir.ptr<!s32i>
 // CIR-BEFORE-LPP:  }
-// CIR: cir.global external tls_dyn dyn_tls_refs = <"_ZTW17tls_int_self_init", 
"_ZTH17tls_int_self_init"> @tls_int_self_init = #cir.int<0> : !s32i
+// CIR: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW17tls_int_self_init", "_ZTH17tls_int_self_init"> @tls_int_self_init = 
#cir.int<0> : !s32i
 // CIR: cir.func internal private @[[TLS_INT_SELF_REF_INIT]]() {
 // CIR:   %[[GET_GLOB:.*]] = cir.get_global thread_local @tls_int_self_init : 
!cir.ptr<!s32i>
 // CIR:   %[[GET_SELF_FROM_WRAPPER:.*]] = cir.call @_ZTW17tls_int_self_init() 
: () -> !cir.ptr<!s32i>
@@ -223,16 +223,16 @@ thread_local int tls_int_self_init = tls_int_self_init + 
get_i();
 // OGCG:   ret ptr %[[GET_GLOB]]
 
 extern thread_local int definitely_inited = 5;
-// CIR-BEFORE-LPP: cir.global external tls_dyn dyn_tls_refs = 
<"_ZTW17definitely_inited", "_ZTH17definitely_inited"> @definitely_inited = 
#cir.int<5> : !s32i
-// CIR: cir.global external tls_dyn dyn_tls_refs = <"_ZTW17definitely_inited", 
"_ZTH17definitely_inited"> @definitely_inited = #cir.int<5> : !s32i
+// CIR-BEFORE-LPP: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW17definitely_inited", "_ZTH17definitely_inited"> @definitely_inited = 
#cir.int<5> : !s32i
+// CIR: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW17definitely_inited", "_ZTH17definitely_inited"> @definitely_inited = 
#cir.int<5> : !s32i
 
 extern thread_local int definitely_inited_dyn = get_i();
-// CIR-BEFORE-LPP: cir.global external tls_dyn dyn_tls_refs = 
<"_ZTW21definitely_inited_dyn", "_ZTH21definitely_inited_dyn"> 
@definitely_inited_dyn = ctor : !s32i {
+// CIR-BEFORE-LPP: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW21definitely_inited_dyn", "_ZTH21definitely_inited_dyn"> 
@definitely_inited_dyn = ctor : !s32i {
 // CIR-BEFORE-LPP:   %[[GET_GLOB:.*]] = cir.get_global thread_local 
@definitely_inited_dyn : !cir.ptr<!s32i>
 // CIR-BEFORE-LPP:   %[[CALL:.*]] = cir.call @_Z5get_iv() : () -> (!s32i 
{llvm.noundef})
 // CIR-BEFORE-LPP:   cir.store {{.*}}%[[CALL]], %[[GET_GLOB]] : !s32i, 
!cir.ptr<!s32i>
 // CIR-BEFORE-LPP: }
-// CIR: cir.global external tls_dyn dyn_tls_refs = 
<"_ZTW21definitely_inited_dyn", "_ZTH21definitely_inited_dyn"> 
@definitely_inited_dyn = #cir.int<0> : !s32i
+// CIR: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW21definitely_inited_dyn", "_ZTH21definitely_inited_dyn"> 
@definitely_inited_dyn = #cir.int<0> : !s32i
 // CIR: cir.func internal private @[[DEF_INITED_DYN]]() {
 // CIR:   %[[GET_GLOB:.*]] = cir.get_global thread_local 
@definitely_inited_dyn : !cir.ptr<!s32i>
 // CIR:   %[[CALL:.*]] = cir.call @_Z5get_iv() : () -> (!s32i {llvm.noundef})
@@ -247,8 +247,8 @@ extern thread_local int definitely_inited_dyn = get_i();
 // LLVM-BOTH:   ret void
 
 extern thread_local int maybe_inited;
-// CIR-BEFORE-LPP: cir.global "private" external tls_dyn dyn_tls_refs = 
<"_ZTW12maybe_inited", "_ZTH12maybe_inited"> @maybe_inited : !s32i
-// CIR: cir.global "private" external tls_dyn dyn_tls_refs = 
<"_ZTW12maybe_inited", "_ZTH12maybe_inited"> @maybe_inited : !s32i
+// CIR-BEFORE-LPP: cir.global "private" external tls_model = <tls_dyn> 
dyn_tls_refs = <"_ZTW12maybe_inited", "_ZTH12maybe_inited"> @maybe_inited : 
!s32i
+// CIR: cir.global "private" external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW12maybe_inited", "_ZTH12maybe_inited"> @maybe_inited : !s32i
 
 void uses() {
   auto a = tls_int;
diff --git a/clang/test/CIR/CodeGen/global-tls-templates.cpp 
b/clang/test/CIR/CodeGen/global-tls-templates.cpp
index 81bb2e54334a6..d8c5acc2e0afd 100644
--- a/clang/test/CIR/CodeGen/global-tls-templates.cpp
+++ b/clang/test/CIR/CodeGen/global-tls-templates.cpp
@@ -13,13 +13,13 @@ struct CtorDtor {
 template<typename T>
 thread_local T tls_templ = {get_i()};
 
-// CIR-BEFORE-LPP-LABEL:  cir.global linkonce_odr comdat tls_dyn dyn_tls_refs 
= <"_ZTW9tls_templIiE", "_ZTH9tls_templIiE", "_ZGV9tls_templIiE"> 
@_Z9tls_templIiE = ctor : !s32i {
+// CIR-BEFORE-LPP-LABEL:  cir.global linkonce_odr comdat tls_model = <tls_dyn> 
dyn_tls_refs = <"_ZTW9tls_templIiE", "_ZTH9tls_templIiE", "_ZGV9tls_templIiE"> 
@_Z9tls_templIiE = ctor : !s32i {
 // CIR-BEFORE-LPP:    %[[GET_GLOB:.*]] = cir.get_global thread_local 
@_Z9tls_templIiE : !cir.ptr<!s32i>
 // CIR-BEFORE-LPP:    %[[CALL:.*]] = cir.call @_Z5get_iv() : () -> (!s32i 
{llvm.noundef})
 // CIR-BEFORE-LPP:    cir.store{{.*}} %[[CALL]], %[[GET_GLOB]] : !s32i, 
!cir.ptr<!s32i>
 // CIR-BEFORE-LPP:  }
 //
-// CIR-BEFORE-LPP-LABEL:  cir.global linkonce_odr comdat tls_dyn dyn_tls_refs 
= <"_ZTW9tls_templI8CtorDtorE", "_ZTH9tls_templI8CtorDtorE", 
"_ZGV9tls_templI8CtorDtorE"> @_Z9tls_templI8CtorDtorE = ctor : !rec_CtorDtor {
+// CIR-BEFORE-LPP-LABEL:  cir.global linkonce_odr comdat tls_model = <tls_dyn> 
dyn_tls_refs = <"_ZTW9tls_templI8CtorDtorE", "_ZTH9tls_templI8CtorDtorE", 
"_ZGV9tls_templI8CtorDtorE"> @_Z9tls_templI8CtorDtorE = ctor : !rec_CtorDtor {
 // CIR-BEFORE-LPP:    %[[GET_GLOB:.*]] = cir.get_global thread_local 
@_Z9tls_templI8CtorDtorE : !cir.ptr<!rec_CtorDtor>
 // CIR-BEFORE-LPP:    %[[CALL:.*]] = cir.call @_Z5get_iv() : () -> (!s32i 
{llvm.noundef})
 // CIR-BEFORE-LPP:    cir.call @_ZN8CtorDtorC1Ei(%[[GET_GLOB]], %[[CALL]]) : 
(!cir.ptr<!rec_CtorDtor>
@@ -38,7 +38,7 @@ thread_local T tls_templ = {get_i()};
 // Alias: Ctor/Dtor: 
 // CIR: cir.func linkonce_odr @_ZTH9tls_templI8CtorDtorE() 
alias(@[[CTOR_DTOR_INIT:[^)]*]])
 // TLS Guard: Ctor/Dtor:
-// CIR: cir.global "private" linkonce_odr comdat tls_dyn 
@_ZGV9tls_templI8CtorDtorE = #cir.int<0> : !s64i
+// CIR: cir.global "private" linkonce_odr comdat tls_model = <tls_dyn> 
@_ZGV9tls_templI8CtorDtorE = #cir.int<0> : !s64i
 
 // Wrapper: int
 // CIR-LABEL: cir.func comdat weak_odr private hidden @_ZTW9tls_templIiE() -> 
!cir.ptr<!s32i>
@@ -50,10 +50,10 @@ thread_local T tls_templ = {get_i()};
 // Alias: int
 // CIR: cir.func linkonce_odr @_ZTH9tls_templIiE() alias(@[[INT_INIT:[^)]*]])
 // TLS Guard: int
-// CIR: cir.global "private" linkonce_odr comdat tls_dyn @_ZGV9tls_templIiE = 
#cir.int<0> : !s64i
+// CIR: cir.global "private" linkonce_odr comdat tls_model = <tls_dyn> 
@_ZGV9tls_templIiE = #cir.int<0> : !s64i
 
 // Global: int
-// CIR: cir.global linkonce_odr comdat tls_dyn dyn_tls_refs = 
<"_ZTW9tls_templIiE", "_ZTH9tls_templIiE", "_ZGV9tls_templIiE"> 
@_Z9tls_templIiE = #cir.int<0> : !s32i
+// CIR: cir.global linkonce_odr comdat tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW9tls_templIiE", "_ZTH9tls_templIiE", "_ZGV9tls_templIiE"> 
@_Z9tls_templIiE = #cir.int<0> : !s32i
 
 // Init Func: int
 // CIR:  cir.func internal private @[[INT_INIT]]() {
@@ -74,7 +74,7 @@ thread_local T tls_templ = {get_i()};
 
 
 // Global: Ctor/Dotr:
-// CIR: cir.global linkonce_odr comdat tls_dyn dyn_tls_refs = 
<"_ZTW9tls_templI8CtorDtorE", "_ZTH9tls_templI8CtorDtorE", 
"_ZGV9tls_templI8CtorDtorE"> @_Z9tls_templI8CtorDtorE = #cir.zero : 
!rec_CtorDtor
+// CIR: cir.global linkonce_odr comdat tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW9tls_templI8CtorDtorE", "_ZTH9tls_templI8CtorDtorE", 
"_ZGV9tls_templI8CtorDtorE"> @_Z9tls_templI8CtorDtorE = #cir.zero : 
!rec_CtorDtor
 
 // Init Func: Ctor/Dtor:
 // CIR: cir.func internal private @[[CTOR_DTOR_INIT]]() {
diff --git a/clang/test/CIR/CodeGen/thread-local-in-func.cpp 
b/clang/test/CIR/CodeGen/thread-local-in-func.cpp
index 0d8466ab41471..04542164dade2 100644
--- a/clang/test/CIR/CodeGen/thread-local-in-func.cpp
+++ b/clang/test/CIR/CodeGen/thread-local-in-func.cpp
@@ -4,32 +4,32 @@
 // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-llvm %s 
-o - | FileCheck %s --check-prefix=OGCG,LLVM-BOTH
 
 // Guard variables.
-// CIR-DAG: cir.global "private" internal tls_dyn dso_local 
@_ZGVZ13test_ctordtoriE4init = #cir.int<0> : !s8i
+// CIR-DAG: cir.global "private" internal tls_model = <tls_dyn> dso_local 
@_ZGVZ13test_ctordtoriE4init = #cir.int<0> : !s8i
 // LLVM-BOTH-DAG: @_ZGVZ13test_ctordtoriE4init = internal thread_local global 
i8 0
-// CIR-DAG: cir.global "private" internal tls_dyn dso_local 
@_ZGVZ13test_ctordtoriE10const_init = #cir.int<0> : !s8i
+// CIR-DAG: cir.global "private" internal tls_model = <tls_dyn> dso_local 
@_ZGVZ13test_ctordtoriE10const_init = #cir.int<0> : !s8i
 // LLVM-BOTH-DAG: @_ZGVZ13test_ctordtoriE10const_init = internal thread_local 
global i8 0
-// CIR-DAG: cir.global "private" internal tls_dyn dso_local 
@_ZGVZ9test_dtoriE10const_init = #cir.int<0> : !s8i
+// CIR-DAG: cir.global "private" internal tls_model = <tls_dyn> dso_local 
@_ZGVZ9test_dtoriE10const_init = #cir.int<0> : !s8i
 // LLVM-BOTH-DAG: @_ZGVZ9test_dtoriE10const_init = internal thread_local 
global i8 0
-// CIR-DAG: cir.global "private" internal tls_dyn dso_local 
@_ZGVZ9test_ctoriE4init = #cir.int<0> : !s8i
+// CIR-DAG: cir.global "private" internal tls_model = <tls_dyn> dso_local 
@_ZGVZ9test_ctoriE4init = #cir.int<0> : !s8i
 // LLVM-BOTH-DAG: @_ZGVZ9test_ctoriE4init = internal thread_local global i8 0
-// CIR-DAG: cir.global "private" internal tls_dyn dso_local 
@_ZGVZ9test_ctoriE10const_init = #cir.int<0> : !s8i
+// CIR-DAG: cir.global "private" internal tls_model = <tls_dyn> dso_local 
@_ZGVZ9test_ctoriE10const_init = #cir.int<0> : !s8i
 // LLVM-BOTH-DAG: @_ZGVZ9test_ctoriE10const_init = internal thread_local 
global i8 0
-// CIR-DAG: cir.global "private" internal tls_dyn dso_local 
@_ZGVZ8test_intiE4init = #cir.int<0> : !s8i
+// CIR-DAG: cir.global "private" internal tls_model = <tls_dyn> dso_local 
@_ZGVZ8test_intiE4init = #cir.int<0> : !s8i
 // LLVM-BOTH-DAG: @_ZGVZ8test_intiE4init = internal thread_local global i8 0
 
-// CIR-BOTH-DAG: cir.global "private" internal tls_dyn dso_local 
static_local_guard<"_ZGVZ13test_ctordtoriE4init"> @_ZZ13test_ctordtoriE4init = 
#cir.zero : !rec_CtorDtor
+// CIR-BOTH-DAG: cir.global "private" internal tls_model = <tls_dyn> dso_local 
static_local_guard<"_ZGVZ13test_ctordtoriE4init"> @_ZZ13test_ctordtoriE4init = 
#cir.zero : !rec_CtorDtor
 // LLVM-BOTH-DAG: @_ZZ13test_ctordtoriE4init = internal thread_local global 
%struct.CtorDtor zeroinitializer
-// CIR-BOTH-DAG: cir.global "private" internal tls_dyn dso_local 
static_local_guard<"_ZGVZ13test_ctordtoriE10const_init"> 
@_ZZ13test_ctordtoriE10const_init = #cir.zero : !rec_CtorDtor
+// CIR-BOTH-DAG: cir.global "private" internal tls_model = <tls_dyn> dso_local 
static_local_guard<"_ZGVZ13test_ctordtoriE10const_init"> 
@_ZZ13test_ctordtoriE10const_init = #cir.zero : !rec_CtorDtor
 // LLVM-BOTH-DAG: @_ZZ13test_ctordtoriE10const_init = internal thread_local 
global %struct.CtorDtor zeroinitializer
-// CIR-BOTH-DAG: cir.global "private" internal tls_dyn dso_local 
static_local_guard<"_ZGVZ9test_dtoriE10const_init"> 
@_ZZ9test_dtoriE10const_init = #cir.zero : !rec_Dtor
+// CIR-BOTH-DAG: cir.global "private" internal tls_model = <tls_dyn> dso_local 
static_local_guard<"_ZGVZ9test_dtoriE10const_init"> 
@_ZZ9test_dtoriE10const_init = #cir.zero : !rec_Dtor
 // LLVM-BOTH-DAG: @_ZZ9test_dtoriE10const_init = internal thread_local global 
%struct.Dtor zeroinitializer
-// CIR-BOTH-DAG: cir.global "private" internal tls_dyn dso_local 
static_local_guard<"_ZGVZ9test_ctoriE4init"> @_ZZ9test_ctoriE4init = #cir.zero 
: !rec_Ctor
+// CIR-BOTH-DAG: cir.global "private" internal tls_model = <tls_dyn> dso_local 
static_local_guard<"_ZGVZ9test_ctoriE4init"> @_ZZ9test_ctoriE4init = #cir.zero 
: !rec_Ctor
 // LLVM-BOTH-DAG: @_ZZ9test_ctoriE4init = internal thread_local global 
%struct.Ctor zeroinitializer
-// CIR-BOTH-DAG: cir.global "private" internal tls_dyn dso_local 
static_local_guard<"_ZGVZ9test_ctoriE10const_init"> 
@_ZZ9test_ctoriE10const_init = #cir.zero : !rec_Ctor
+// CIR-BOTH-DAG: cir.global "private" internal tls_model = <tls_dyn> dso_local 
static_local_guard<"_ZGVZ9test_ctoriE10const_init"> 
@_ZZ9test_ctoriE10const_init = #cir.zero : !rec_Ctor
 // LLVM-BOTH-DAG: @_ZZ9test_ctoriE10const_init = internal thread_local global 
%struct.Ctor zeroinitializer
-// CIR-BOTH-DAG: cir.global "private" internal tls_dyn dso_local 
static_local_guard<"_ZGVZ8test_intiE4init"> @_ZZ8test_intiE4init = #cir.int<0> 
: !s32i
+// CIR-BOTH-DAG: cir.global "private" internal tls_model = <tls_dyn> dso_local 
static_local_guard<"_ZGVZ8test_intiE4init"> @_ZZ8test_intiE4init = #cir.int<0> 
: !s32i
 // LLVM-BOTH-DAG: @_ZZ8test_intiE4init = internal thread_local global i32 0
-// CIR-BOTH-DAG: cir.global "private" internal tls_dyn dso_local 
@_ZZ8test_intiE10const_init = #cir.int<5> : !s32i
+// CIR-BOTH-DAG: cir.global "private" internal tls_model = <tls_dyn> dso_local 
@_ZZ8test_intiE10const_init = #cir.int<5> : !s32i
 // LLVM-BOTH-DAG: @_ZZ8test_intiE10const_init = internal thread_local global 
i32 5
 int get_i();
 
diff --git a/clang/test/CIR/CodeGen/tls-model-func-scope.cpp 
b/clang/test/CIR/CodeGen/tls-model-func-scope.cpp
index 5567b6fdd9660..f9a32f5643f37 100644
--- a/clang/test/CIR/CodeGen/tls-model-func-scope.cpp
+++ b/clang/test/CIR/CodeGen/tls-model-func-scope.cpp
@@ -32,10 +32,10 @@ void func() {
 }
 // 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
+// CIR-GD: cir.global "private" internal tls_model = <tls_init_exec> dso_local 
@_ZGVZ4funcvE17override_tls_mode = #cir.int<0> : !s8i
+// CIR-GD: cir.global "private" internal tls_model = <tls_dyn> dso_local 
@_ZGVZ4funcvE16default_tls_mode = #cir.int<0> : !s8i
+// CIR-GD: cir.global "private" internal tls_model = <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_model = <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
@@ -44,10 +44,10 @@ void func() {
 
 // 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
+// CIR-LD: cir.global "private" internal tls_model = <tls_init_exec> dso_local 
@_ZGVZ4funcvE17override_tls_mode = #cir.int<0> : !s8i
+// CIR-LD: cir.global "private" internal tls_model = <tls_local_dyn> dso_local 
@_ZGVZ4funcvE16default_tls_mode = #cir.int<0> : !s8i
+// CIR-LD: cir.global "private" internal tls_model = <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_model = <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
@@ -56,10 +56,10 @@ void func() {
 
 // 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<"_ZGVZ4funcvE16default_tls_mode"> 
@_ZZ4funcvE16default_tls_mode = #cir.int<0> : !s32i
+// CIR-IE: cir.global "private" internal tls_model = <tls_init_exec> dso_local 
@_ZGVZ4funcvE17override_tls_mode = #cir.int<0> : !s8i
+// CIR-IE: cir.global "private" internal tls_model = <tls_init_exec> dso_local 
@_ZGVZ4funcvE16default_tls_mode = #cir.int<0> : !s8i
+// CIR-IE: cir.global "private" internal tls_model = <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_model = <tls_init_exec> dso_local 
static_local_guard<"_ZGVZ4funcvE16default_tls_mode"> 
@_ZZ4funcvE16default_tls_mode = #cir.int<0> : !s32i
 
 // LLVM-IE-DAG: @_ZGVZ4funcvE17override_tls_mode = internal 
thread_local(initialexec) global i8 0
 // LLVM-IE-DAG: @_ZGVZ4funcvE16default_tls_mode = internal 
thread_local(initialexec) global i8 0
@@ -68,10 +68,10 @@ void func() {
 
 // CIR-LE: module {{.*}} attributes
 // CIR-LE-SAME: cir.default.tls_model = #cir.tls_model<tls_local_exec>
-// CIR-LE: cir.global "private" internal tls_init_exec dso_local 
@_ZGVZ4funcvE17override_tls_mode = #cir.int<0> : !s8i
-// CIR-LE: cir.global "private" internal tls_local_exec dso_local 
@_ZGVZ4funcvE16default_tls_mode = #cir.int<0> : !s8i
-// CIR-LE: cir.global "private" internal tls_init_exec dso_local 
static_local_guard<"_ZGVZ4funcvE17override_tls_mode"> 
@_ZZ4funcvE17override_tls_mode = #cir.int<0> : !s32i
-// CIR-LE: cir.global "private" internal tls_local_exec dso_local 
static_local_guard<"_ZGVZ4funcvE16default_tls_mode"> 
@_ZZ4funcvE16default_tls_mode = #cir.int<0> : !s32i
+// CIR-LE: cir.global "private" internal tls_model = <tls_init_exec> dso_local 
@_ZGVZ4funcvE17override_tls_mode = #cir.int<0> : !s8i
+// CIR-LE: cir.global "private" internal tls_model = <tls_local_exec> 
dso_local @_ZGVZ4funcvE16default_tls_mode = #cir.int<0> : !s8i
+// CIR-LE: cir.global "private" internal tls_model = <tls_init_exec> dso_local 
static_local_guard<"_ZGVZ4funcvE17override_tls_mode"> 
@_ZZ4funcvE17override_tls_mode = #cir.int<0> : !s32i
+// CIR-LE: cir.global "private" internal tls_model = <tls_local_exec> 
dso_local static_local_guard<"_ZGVZ4funcvE16default_tls_mode"> 
@_ZZ4funcvE16default_tls_mode = #cir.int<0> : !s32i
 
 // LLVM-LE-DAG: @_ZGVZ4funcvE17override_tls_mode = internal 
thread_local(initialexec) global i8 0
 // LLVM-LE-DAG: @_ZGVZ4funcvE16default_tls_mode = internal 
thread_local(localexec) global i8 0
diff --git a/clang/test/CIR/CodeGen/tls-model.cpp 
b/clang/test/CIR/CodeGen/tls-model.cpp
index e686faf585036..6aafd9393d5dd 100644
--- a/clang/test/CIR/CodeGen/tls-model.cpp
+++ b/clang/test/CIR/CodeGen/tls-model.cpp
@@ -50,12 +50,12 @@ struct T thread_local t1;
 // CIR-GD-SAME: cir.default.tls_model = #cir.tls_model<tls_dyn>
 // CIR-GD-DAG: cir.global external @z1 = #cir.int<0> : !s32i {alignment = 4 : 
i64}
 // CIR-GD-DAG: cir.global external @z2 = #cir.int<0> : !s32i {alignment = 4 : 
i64}
-// CIR-GD-DAG: cir.global external tls_dyn dyn_tls_refs = <"_ZTW1x", "_ZTH1x"> 
@x = #cir.int<0> : !s32i {alignment = 4 : i64}
-// CIR-GD-DAG: cir.global "private" internal tls_dyn dso_local @_ZZ1fvE1y = 
#cir.int<0> : !s32i {alignment = 4 : i64}
-// CIR-GD-DAG: cir.global external tls_init_exec dyn_tls_refs = <"_ZTW1z", 
"_ZTH1z"> @z = #cir.int<0> : !s32i {alignment = 4 : i64}
-// CIR-GD-DAG: cir.global external tls_dyn dyn_tls_refs = <"_ZTW2s1", 
"_ZTH2s1"> @s1 = #cir.zero : !rec_S {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
-// CIR-GD-DAG: cir.global external tls_dyn dyn_tls_refs = <"_ZTW2t1", 
"_ZTH2t1"> @t1 = #cir.zero : !rec_T {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
-// CIR-GD-DAG: cir.global internal tls_dyn @__tls_guard = #cir.int<0> : !s8i 
{alignment = 1 : i64}
+// CIR-GD-DAG: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW1x", "_ZTH1x"> @x = #cir.int<0> : !s32i {alignment = 4 : i64}
+// CIR-GD-DAG: cir.global "private" internal tls_model = <tls_dyn> dso_local 
@_ZZ1fvE1y = #cir.int<0> : !s32i {alignment = 4 : i64}
+// CIR-GD-DAG: cir.global external tls_model = <tls_init_exec> dyn_tls_refs = 
<"_ZTW1z", "_ZTH1z"> @z = #cir.int<0> : !s32i {alignment = 4 : i64}
+// CIR-GD-DAG: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW2s1", "_ZTH2s1"> @s1 = #cir.zero : !rec_S {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
+// CIR-GD-DAG: cir.global external tls_model = <tls_dyn> dyn_tls_refs = 
<"_ZTW2t1", "_ZTH2t1"> @t1 = #cir.zero : !rec_T {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
+// CIR-GD-DAG: cir.global internal tls_model = <tls_dyn> @__tls_guard = 
#cir.int<0> : !s8i {alignment = 1 : i64}
 
 // LLVM-GD-DAG: @z1 ={{.*}} global i32 0
 // LLVM-GD-DAG: @z2 ={{.*}} global i32 0
@@ -70,12 +70,12 @@ struct T thread_local t1;
 // CIR-LD-SAME: cir.default.tls_model = #cir.tls_model<tls_local_dyn>
 // CIR-LD-DAG: cir.global external @z1 = #cir.int<0> : !s32i {alignment = 4 : 
i64}
 // CIR-LD-DAG: cir.global external @z2 = #cir.int<0> : !s32i {alignment = 4 : 
i64}
-// CIR-LD-DAG: cir.global external tls_local_dyn dyn_tls_refs = <"_ZTW1x", 
"_ZTH1x"> @x = #cir.int<0> : !s32i {alignment = 4 : i64}
-// CIR-LD-DAG: cir.global "private" internal tls_local_dyn dso_local 
@_ZZ1fvE1y = #cir.int<0> : !s32i {alignment = 4 : i64}
-// CIR-LD-DAG: cir.global external tls_init_exec dyn_tls_refs = <"_ZTW1z", 
"_ZTH1z"> @z = #cir.int<0> : !s32i {alignment = 4 : i64}
-// CIR-LD-DAG: cir.global external tls_local_dyn dyn_tls_refs = <"_ZTW2s1", 
"_ZTH2s1"> @s1 = #cir.zero : !rec_S {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
-// CIR-LD-DAG: cir.global external tls_local_dyn dyn_tls_refs = <"_ZTW2t1", 
"_ZTH2t1"> @t1 = #cir.zero : !rec_T {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
-// CIR-LD-DAG: cir.global internal tls_local_dyn @__tls_guard = #cir.int<0> : 
!s8i {alignment = 1 : i64}
+// CIR-LD-DAG: cir.global external tls_model = <tls_local_dyn> dyn_tls_refs = 
<"_ZTW1x", "_ZTH1x"> @x = #cir.int<0> : !s32i {alignment = 4 : i64}
+// CIR-LD-DAG: cir.global "private" internal tls_model = <tls_local_dyn> 
dso_local @_ZZ1fvE1y = #cir.int<0> : !s32i {alignment = 4 : i64}
+// CIR-LD-DAG: cir.global external tls_model = <tls_init_exec> dyn_tls_refs = 
<"_ZTW1z", "_ZTH1z"> @z = #cir.int<0> : !s32i {alignment = 4 : i64}
+// CIR-LD-DAG: cir.global external tls_model = <tls_local_dyn> dyn_tls_refs = 
<"_ZTW2s1", "_ZTH2s1"> @s1 = #cir.zero : !rec_S {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
+// CIR-LD-DAG: cir.global external tls_model = <tls_local_dyn> dyn_tls_refs = 
<"_ZTW2t1", "_ZTH2t1"> @t1 = #cir.zero : !rec_T {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
+// CIR-LD-DAG: cir.global internal tls_model = <tls_local_dyn> @__tls_guard = 
#cir.int<0> : !s8i {alignment = 1 : i64}
 
 // LLVM-LD-DAG: @z1 ={{.*}} global i32 0
 // LLVM-LD-DAG: @z2 ={{.*}} global i32 0
@@ -90,12 +90,12 @@ struct T thread_local t1;
 // CIR-IE-SAME: cir.default.tls_model = #cir.tls_model<tls_init_exec>
 // CIR-IE-DAG: cir.global external @z1 = #cir.int<0> : !s32i {alignment = 4 : 
i64}
 // CIR-IE-DAG: cir.global external @z2 = #cir.int<0> : !s32i {alignment = 4 : 
i64}
-// CIR-IE-DAG: cir.global external tls_init_exec dyn_tls_refs = <"_ZTW1x", 
"_ZTH1x"> @x = #cir.int<0> : !s32i {alignment = 4 : i64}
-// CIR-IE-DAG: cir.global "private" internal tls_init_exec dso_local 
@_ZZ1fvE1y = #cir.int<0> : !s32i {alignment = 4 : i64}
-// CIR-IE-DAG: cir.global external tls_init_exec dyn_tls_refs = <"_ZTW1z", 
"_ZTH1z"> @z = #cir.int<0> : !s32i {alignment = 4 : i64}
-// CIR-IE-DAG: cir.global external tls_init_exec dyn_tls_refs = <"_ZTW2s1", 
"_ZTH2s1"> @s1 = #cir.zero : !rec_S {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
-// CIR-IE-DAG: cir.global external tls_init_exec dyn_tls_refs = <"_ZTW2t1", 
"_ZTH2t1"> @t1 = #cir.zero : !rec_T {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
-// CIR-IE-DAG: cir.global internal tls_init_exec @__tls_guard = #cir.int<0> : 
!s8i {alignment = 1 : i64}
+// CIR-IE-DAG: cir.global external tls_model = <tls_init_exec> dyn_tls_refs = 
<"_ZTW1x", "_ZTH1x"> @x = #cir.int<0> : !s32i {alignment = 4 : i64}
+// CIR-IE-DAG: cir.global "private" internal tls_model = <tls_init_exec> 
dso_local @_ZZ1fvE1y = #cir.int<0> : !s32i {alignment = 4 : i64}
+// CIR-IE-DAG: cir.global external tls_model = <tls_init_exec> dyn_tls_refs = 
<"_ZTW1z", "_ZTH1z"> @z = #cir.int<0> : !s32i {alignment = 4 : i64}
+// CIR-IE-DAG: cir.global external tls_model = <tls_init_exec> dyn_tls_refs = 
<"_ZTW2s1", "_ZTH2s1"> @s1 = #cir.zero : !rec_S {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
+// CIR-IE-DAG: cir.global external tls_model = <tls_init_exec> dyn_tls_refs = 
<"_ZTW2t1", "_ZTH2t1"> @t1 = #cir.zero : !rec_T {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
+// CIR-IE-DAG: cir.global internal tls_model = <tls_init_exec> @__tls_guard = 
#cir.int<0> : !s8i {alignment = 1 : i64}
 
 // LLVM-IE-DAG: @z1 ={{.*}} global i32 0
 // LLVM-IE-DAG: @z2 ={{.*}} global i32 0
@@ -110,12 +110,12 @@ struct T thread_local t1;
 // CIR-LE-SAME: cir.default.tls_model = #cir.tls_model<tls_local_exec>
 // CIR-LE-DAG: cir.global external @z1 = #cir.int<0> : !s32i {alignment = 4 : 
i64}
 // CIR-LE-DAG: cir.global external @z2 = #cir.int<0> : !s32i {alignment = 4 : 
i64}
-// CIR-LE-DAG: cir.global external tls_local_exec dyn_tls_refs = <"_ZTW1x", 
"_ZTH1x"> @x = #cir.int<0> : !s32i {alignment = 4 : i64}
-// CIR-LE-DAG: cir.global "private" internal tls_local_exec dso_local 
@_ZZ1fvE1y = #cir.int<0> : !s32i {alignment = 4 : i64}
-// CIR-LE-DAG: cir.global external tls_init_exec dyn_tls_refs = <"_ZTW1z", 
"_ZTH1z"> @z = #cir.int<0> : !s32i {alignment = 4 : i64}
-// CIR-LE-DAG: cir.global external tls_local_exec dyn_tls_refs = <"_ZTW2s1", 
"_ZTH2s1"> @s1 = #cir.zero : !rec_S {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
-// CIR-LE-DAG: cir.global external tls_local_exec dyn_tls_refs = <"_ZTW2t1", 
"_ZTH2t1"> @t1 = #cir.zero : !rec_T {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
-// CIR-LE-DAG: cir.global internal tls_local_exec @__tls_guard = #cir.int<0> : 
!s8i {alignment = 1 : i64}
+// CIR-LE-DAG: cir.global external tls_model = <tls_local_exec> dyn_tls_refs = 
<"_ZTW1x", "_ZTH1x"> @x = #cir.int<0> : !s32i {alignment = 4 : i64}
+// CIR-LE-DAG: cir.global "private" internal tls_model = <tls_local_exec> 
dso_local @_ZZ1fvE1y = #cir.int<0> : !s32i {alignment = 4 : i64}
+// CIR-LE-DAG: cir.global external tls_model = <tls_init_exec> dyn_tls_refs = 
<"_ZTW1z", "_ZTH1z"> @z = #cir.int<0> : !s32i {alignment = 4 : i64}
+// CIR-LE-DAG: cir.global external tls_model = <tls_local_exec> dyn_tls_refs = 
<"_ZTW2s1", "_ZTH2s1"> @s1 = #cir.zero : !rec_S {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
+// CIR-LE-DAG: cir.global external tls_model = <tls_local_exec> dyn_tls_refs = 
<"_ZTW2t1", "_ZTH2t1"> @t1 = #cir.zero : !rec_T {alignment = 1 : i64, ast = 
#cir.var.decl.ast}
+// CIR-LE-DAG: cir.global internal tls_model = <tls_local_exec> @__tls_guard = 
#cir.int<0> : !s8i {alignment = 1 : i64}
 
 // LLVM-LE-DAG: @z1 ={{.*}} global i32 0
 // LLVM-LE-DAG: @z2 ={{.*}} global i32 0
diff --git a/clang/test/CIR/CodeGen/tls.c b/clang/test/CIR/CodeGen/tls.c
index 582a716f0fa73..5fa7f0d9e527d 100644
--- a/clang/test/CIR/CodeGen/tls.c
+++ b/clang/test/CIR/CodeGen/tls.c
@@ -6,10 +6,10 @@
 // RUN: FileCheck --check-prefix=OGCG --input-file=%t.ogcg.ll %s
 
 extern __thread int b;
-// CIR: cir.global "private" external tls_dyn @b : !s32i
+// CIR: cir.global "private" external tls_model = <tls_dyn> @b : !s32i
 
 __thread int a;
-// CIR: cir.global external tls_dyn @a = #cir.int<0> : !s32i
+// CIR: cir.global external tls_model = <tls_dyn> @a = #cir.int<0> : !s32i
 
 int c(void) { return *&b; }
 // CIR: cir.func no_inline dso_local @c() -> !s32i
diff --git a/clang/test/CIR/IR/global.cir b/clang/test/CIR/IR/global.cir
index 3e78fa627b4aa..8af73871c2725 100644
--- a/clang/test/CIR/IR/global.cir
+++ b/clang/test/CIR/IR/global.cir
@@ -49,10 +49,10 @@ module attributes {cir.triple = "x86_64-unknown-linux-gnu"} 
{
   cir.global external @fp = #cir.ptr<null> : !cir.ptr<!cir.func<()>>
   cir.global external @fpii = #cir.ptr<null> : !cir.ptr<!cir.func<(!s32i) -> 
!s32i>>
   cir.global external @fpvar = #cir.ptr<null> : !cir.ptr<!cir.func<(!s32i, 
...)>>
-  cir.global external tls_dyn @tls1 = #cir.int<0> : !s8i
-  cir.global external tls_local_dyn @tls2 = #cir.int<0> : !s8i
-  cir.global external tls_init_exec @tls3 = #cir.int<0> : !s8i
-  cir.global external tls_local_exec @tls4 = #cir.int<0> : !s8i
+  cir.global external tls_model = <tls_dyn> @tls1 = #cir.int<0> : !s8i
+  cir.global external tls_model = <tls_local_dyn> @tls2 = #cir.int<0> : !s8i
+  cir.global external tls_model = <tls_init_exec> @tls3 = #cir.int<0> : !s8i
+  cir.global external tls_model = <tls_local_exec> @tls4 = #cir.int<0> : !s8i
 }
 
 // CHECK: cir.global external @c = #cir.int<0> : !s8i
@@ -91,7 +91,7 @@ module attributes {cir.triple = "x86_64-unknown-linux-gnu"} {
 // CHECK: cir.global external @fp = #cir.ptr<null> : !cir.ptr<!cir.func<()>>
 // CHECK: cir.global external @fpii = #cir.ptr<null> : 
!cir.ptr<!cir.func<(!s32i) -> !s32i>>
 // CHECK: cir.global external @fpvar = #cir.ptr<null> : 
!cir.ptr<!cir.func<(!s32i, ...)>>
-// CHECK: cir.global external tls_dyn @tls1 = #cir.int<0> : !s8i
-// CHECK: cir.global external tls_local_dyn @tls2 = #cir.int<0> : !s8i
-// CHECK: cir.global external tls_init_exec @tls3 = #cir.int<0> : !s8i
-// CHECK: cir.global external tls_local_exec @tls4 = #cir.int<0> : !s8i
+// CHECK: cir.global external tls_model = <tls_dyn> @tls1 = #cir.int<0> : !s8i
+// CHECK: cir.global external tls_model = <tls_local_dyn> @tls2 = #cir.int<0> 
: !s8i
+// CHECK: cir.global external tls_model = <tls_init_exec> @tls3 = #cir.int<0> 
: !s8i
+// CHECK: cir.global external tls_model = <tls_local_exec> @tls4 = #cir.int<0> 
: !s8i
diff --git a/clang/test/CIR/IR/invalid-tls.cir 
b/clang/test/CIR/IR/invalid-tls.cir
index de10382b9ae1e..56d07803ce62c 100644
--- a/clang/test/CIR/IR/invalid-tls.cir
+++ b/clang/test/CIR/IR/invalid-tls.cir
@@ -17,7 +17,7 @@ module {
 
 module {
   // expected-error@+1{{op cannot have both static local and dynamic tls 
references}}
-cir.global "private" internal tls_dyn dyn_tls_refs = <"asdf", "asdf", "asdf"> 
static_local_guard<"asdf"> @_ZZ1fvE1y : !s32i
+cir.global "private" internal tls_model = <tls_dyn> dyn_tls_refs = <"asdf", 
"asdf", "asdf"> static_local_guard<"asdf"> @_ZZ1fvE1y : !s32i
 }
 
 // -----
@@ -25,10 +25,7 @@ cir.global "private" internal tls_dyn dyn_tls_refs = 
<"asdf", "asdf", "asdf"> st
 !s32i = !cir.int<s, 32>
 
 module {
-  // FIXME(cir) Parsing continues on when tls doesn't get recognized, and
-  // unfortunately Address space is the only thing that comes next. We should
-  // probably do a better job having address-space give up if we care enough 
here.
-  // expected-error@+2{{failed to parse Address Space Value for GlobalOp}}
-  // expected-error@+1{{custom op 'cir.global' unknown address space specifier 
'invalid_tls_dyn'}}
-cir.global "private" internal invalid_tls_dyn dyn_tls_refs = <"asdf", "asdf", 
"asdf"> @_ZZ1fvE1y : !s32i
+  // expected-error@+2{{custom op 'cir.global' expected ::cir::TLSModel to be 
one of: tls_dyn, tls_local_dyn, tls_init_exec, tls_local_exec}}
+  // expected-error@+1{{custom op 'cir.global' failed to parse 
CIR_TLSModelAttr parameter 'value' which is to be a `::cir::TLSModel}}
+cir.global "private" internal tls_model = <invalid_tls_dyn> dyn_tls_refs = 
<"asdf", "asdf", "asdf"> @_ZZ1fvE1y : !s32i
 }

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

Reply via email to