[clang] [clang] Add per-global code model attribute (PR #72078)

via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 11 23:44:22 PST 2023


https://github.com/heiher updated https://github.com/llvm/llvm-project/pull/72078

>From e3863873ab817dacf8680763bb42d91f005fe5ea Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Fri, 10 Nov 2023 21:07:48 -0600
Subject: [PATCH 1/6] [clang] Add per-global code model attribute

This patch adds a per-global code model attribute, which can override
the target's code model to access global variables.

Currently, the code model attribute is only supported on LoongArch.
This patch also maps GCC's code model names to LLVM's, which allows
for better compatibility between the two compilers.

Suggested-by: Arthur Eubanks <aeubanks at google.com>
Signed-off-by: WANG Rui <wangrui at loongson.cn>
Link: https://discourse.llvm.org/t/how-to-best-implement-code-model-overriding-for-certain-values/71816
Link: https://discourse.llvm.org/t/rfc-add-per-global-code-model-attribute/74944
---
 clang/include/clang/Basic/Attr.td             |  8 +++++
 clang/include/clang/Basic/AttrDocs.td         |  9 ++++++
 .../clang/Basic/DiagnosticSemaKinds.td        |  2 ++
 clang/lib/CodeGen/CodeGenModule.cpp           | 13 ++++++++
 clang/lib/Sema/SemaDeclAttr.cpp               | 30 +++++++++++++++++++
 clang/test/CodeGen/LoongArch/attributes.c     | 10 +++++++
 ...a-attribute-supported-attributes-list.test |  1 +
 clang/test/Sema/loongarch-attr-model.c        | 13 ++++++++
 8 files changed, 86 insertions(+)
 create mode 100644 clang/test/CodeGen/LoongArch/attributes.c
 create mode 100644 clang/test/Sema/loongarch-attr-model.c

diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 1800f584c7e108..d5b5717f3d77cb 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2718,6 +2718,14 @@ def PragmaClangTextSection : InheritableAttr {
   let Documentation = [InternalOnly];
 }
 
+def CodeModel : InheritableAttr {
+  let Spellings = [GCC<"model">];
+  let Args = [StringArgument<"Model">];
+  let Subjects =
+      SubjectList<[ GlobalVar ], ErrorDiag>;
+  let Documentation = [CodeModelDocs];
+}
+
 def Sentinel : InheritableAttr {
   let Spellings = [GCC<"sentinel">];
   let Args = [DefaultIntArgument<"Sentinel", 0>,
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index b45ec6bbb8d37e..1d37c2da6bec05 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -57,6 +57,15 @@ global variable or function should be in after translation.
   let Heading = "section, __declspec(allocate)";
 }
 
+def CodeModelDocs : Documentation {
+  let Category = DocCatVariable;
+  let Content = [{
+The ``model`` attribute allows you to specify a specific code model a
+global variable should be in after translation.
+  }];
+  let Heading = "model";
+}
+
 def UsedDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 6dfb2d7195203a..d438fdde9ac7eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3408,6 +3408,8 @@ def warn_objc_redundant_literal_use : Warning<
 def err_attr_tlsmodel_arg : Error<"tls_model must be \"global-dynamic\", "
   "\"local-dynamic\", \"initial-exec\" or \"local-exec\"">;
 
+def err_attr_codemodel_arg : Error<"code_model '%0' is not yet supported on this target">;
+
 def err_aix_attr_unsupported_tls_model : Error<"TLS model '%0' is not yet supported on AIX">;
 
 def err_tls_var_aligned_over_maximum : Error<
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index dea58a7ff4146a..1f49721e79ddc4 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -4841,6 +4841,19 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty,
         isExternallyVisible(D->getLinkageAndVisibility().getLinkage()))
       GV->setSection(".cp.rodata");
 
+    // Handle code model attribute
+    if (D->hasAttr<CodeModelAttr>()) {
+      if (const CodeModelAttr *CMA = D->getAttr<CodeModelAttr>()) {
+        auto CM = llvm::StringSwitch<llvm::CodeModel::Model>(CMA->getModel())
+                      .Case("tiny", llvm::CodeModel::Tiny)
+                      .Case("kernel", llvm::CodeModel::Kernel)
+                      .Case("medium", llvm::CodeModel::Medium)
+                      .Case("large", llvm::CodeModel::Large)
+                      .Default(llvm::CodeModel::Small);
+        GV->setCodeModel(CM);
+      }
+    }
+
     // Check if we a have a const declaration with an initializer, we may be
     // able to emit it as available_externally to expose it's value to the
     // optimizer.
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 87c78d742d0ff4..64aa242dbb04f8 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3369,6 +3369,33 @@ static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   }
 }
 
+static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+  StringRef CM;
+  StringRef Str;
+  SourceLocation LiteralLoc;
+  bool Ok = false;
+  // Check that it is a string.
+  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
+    return;
+
+  CM = Str;
+  if (S.getASTContext().getTargetInfo().getTriple().isLoongArch()) {
+    Ok = CM == "normal" || CM == "medium" || CM == "extreme";
+    CM = llvm::StringSwitch<StringRef>(CM)
+             .Case("normal", "small")
+             .Case("extreme", "large")
+             .Default(CM);
+  }
+
+  // Check that the value.
+  if (!Ok) {
+    S.Diag(LiteralLoc, diag::err_attr_codemodel_arg) << Str;
+    return;
+  }
+
+  D->addAttr(::new (S.Context) CodeModelAttr(S.Context, AL, CM));
+}
+
 // This is used for `__declspec(code_seg("segname"))` on a decl.
 // `#pragma code_seg("segname")` uses checkSectionName() instead.
 static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc,
@@ -9309,6 +9336,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
   case ParsedAttr::AT_Section:
     handleSectionAttr(S, D, AL);
     break;
+  case ParsedAttr::AT_CodeModel:
+    handleCodeModelAttr(S, D, AL);
+    break;
   case ParsedAttr::AT_RandomizeLayout:
     handleRandomizeLayoutAttr(S, D, AL);
     break;
diff --git a/clang/test/CodeGen/LoongArch/attributes.c b/clang/test/CodeGen/LoongArch/attributes.c
new file mode 100644
index 00000000000000..a6d086845e29b0
--- /dev/null
+++ b/clang/test/CodeGen/LoongArch/attributes.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm -triple loongarch64 %s -o - | FileCheck %s
+
+// CHECK: @normal ={{.*}} global i32 0, code_model "small"
+int normal __attribute__((model("normal")));
+
+// CHECK: @medium ={{.*}} global i32 0, code_model "medium"
+int medium __attribute__((model("medium")));
+
+// CHECK: @extreme ={{.*}} global i32 0, code_model "large"
+int extreme __attribute__((model("extreme")));
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index dd91f4f88ad685..2b191abdac8b56 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -48,6 +48,7 @@
 // CHECK-NEXT: CarriesDependency (SubjectMatchRule_variable_is_parameter, SubjectMatchRule_objc_method, SubjectMatchRule_function)
 // CHECK-NEXT: Cleanup (SubjectMatchRule_variable_is_local)
 // CHECK-NEXT: CmseNSEntry (SubjectMatchRule_function)
+// CHECK-NEXT: CodeModel (SubjectMatchRule_variable_is_global)
 // CHECK-NEXT: Cold (SubjectMatchRule_function)
 // CHECK-NEXT: Common (SubjectMatchRule_variable)
 // CHECK-NEXT: ConstInit (SubjectMatchRule_variable_is_global)
diff --git a/clang/test/Sema/loongarch-attr-model.c b/clang/test/Sema/loongarch-attr-model.c
new file mode 100644
index 00000000000000..3f32f9fba87687
--- /dev/null
+++ b/clang/test/Sema/loongarch-attr-model.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple loongarch64 -verify -fsyntax-only %s
+
+#if !__has_attribute(model)
+#error "Should support model attribute"
+#endif
+
+int a __attribute((model("tiny"))); // expected-error {{code_model 'tiny' is not yet supported on this target}}
+int b __attribute((model("small"))); // expected-error {{code_model 'small' is not yet supported on this target}}
+int c __attribute((model("normal"))); // no-warning
+int d __attribute((model("kernel"))); // expected-error {{code_model 'kernel' is not yet supported on this target}}
+int e __attribute((model("medium"))); // no-warning
+int f __attribute((model("large"))); // expected-error {{code_model 'large' is not yet supported on this target}}
+int g __attribute((model("extreme"))); // no-warning

>From 12b551c859ed4e5f4a6e4a6f94230dce9bff4e76 Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Tue, 5 Dec 2023 15:45:02 +0800
Subject: [PATCH 2/6] Address xen0n's comments

---
 clang/include/clang/Basic/AttrDocs.td | 5 +++--
 clang/lib/Sema/SemaDeclAttr.cpp       | 2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 1d37c2da6bec05..c3c3d92e7367cd 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -60,8 +60,9 @@ global variable or function should be in after translation.
 def CodeModelDocs : Documentation {
   let Category = DocCatVariable;
   let Content = [{
-The ``model`` attribute allows you to specify a specific code model a
-global variable should be in after translation.
+The ``model`` attribute allows you to use a different code model for
+addressing this variable, than the code model specified by the global
+``-mcmodel`` option.
   }];
   let Heading = "model";
 }
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 64aa242dbb04f8..14f220f9fd0a73 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3387,7 +3387,7 @@ static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
              .Default(CM);
   }
 
-  // Check that the value.
+  // Check that the value is acceptable.
   if (!Ok) {
     S.Diag(LiteralLoc, diag::err_attr_codemodel_arg) << Str;
     return;

>From 3a5cbbcc8303870548ee99fa8c0ca6feccdeeae8 Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Tue, 5 Dec 2023 16:45:58 +0800
Subject: [PATCH 3/6] Add a test case that shows the attribute is not supported
 on a non-LoongArch target

---
 clang/test/Sema/attr-model.c           | 33 ++++++++++++++++++++++++++
 clang/test/Sema/loongarch-attr-model.c | 13 ----------
 2 files changed, 33 insertions(+), 13 deletions(-)
 create mode 100644 clang/test/Sema/attr-model.c
 delete mode 100644 clang/test/Sema/loongarch-attr-model.c

diff --git a/clang/test/Sema/attr-model.c b/clang/test/Sema/attr-model.c
new file mode 100644
index 00000000000000..770d7d91441125
--- /dev/null
+++ b/clang/test/Sema/attr-model.c
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple aarch64 -verify=expected,aarch64 -fsyntax-only %s
+// RUN: %clang_cc1 -triple loongarch64 -verify=expected,loongarch64 -fsyntax-only %s
+// RUN: %clang_cc1 -triple mips64 -verify=expected,mips64 -fsyntax-only %s
+// RUN: %clang_cc1 -triple powerpc64 -verify=expected,powerpc64 -fsyntax-only %s
+// RUN: %clang_cc1 -triple riscv64 -verify=expected,riscv64 -fsyntax-only %s
+// RUN: %clang_cc1 -triple x86_64 -verify=expected,x86_64 -fsyntax-only %s
+
+#if !__has_attribute(model)
+#error "Should support model attribute"
+#endif
+
+int a __attribute((model("tiny")));    // expected-error {{code_model 'tiny' is not yet supported on this target}}
+int b __attribute((model("small")));   // expected-error {{code_model 'small' is not yet supported on this target}}
+int c __attribute((model("normal")));  // aarch64-error {{code_model 'normal' is not yet supported on this target}} \
+                                       // loongarch-no-warning \
+                                       // mips64-error {{code_model 'normal' is not yet supported on this target}} \
+                                       // powerpc64-error {{code_model 'normal' is not yet supported on this target}} \
+                                       // riscv64-error {{code_model 'normal' is not yet supported on this target}} \
+                                       // x86_64-error {{code_model 'normal' is not yet supported on this target}}
+int d __attribute((model("kernel")));  // expected-error {{code_model 'kernel' is not yet supported on this target}}
+int e __attribute((model("medium")));  // aarch64-error {{code_model 'medium' is not yet supported on this target}} \
+                                       // loongarch-no-warning \
+                                       // mips64-error {{code_model 'medium' is not yet supported on this target}} \
+                                       // powerpc64-error {{code_model 'medium' is not yet supported on this target}} \
+                                       // riscv64-error {{code_model 'medium' is not yet supported on this target}} \
+                                       // x86_64-error {{code_model 'medium' is not yet supported on this target}}
+int f __attribute((model("large")));   // expected-error {{code_model 'large' is not yet supported on this target}}
+int g __attribute((model("extreme"))); // aarch64-error {{code_model 'extreme' is not yet supported on this target}} \
+                                       // loongarch64-no-warning \
+                                       // mips64-error {{code_model 'extreme' is not yet supported on this target}} \
+                                       // powerpc64-error {{code_model 'extreme' is not yet supported on this target}} \
+                                       // riscv64-error {{code_model 'extreme' is not yet supported on this target}} \
+                                       // x86_64-error {{code_model 'extreme' is not yet supported on this target}}
diff --git a/clang/test/Sema/loongarch-attr-model.c b/clang/test/Sema/loongarch-attr-model.c
deleted file mode 100644
index 3f32f9fba87687..00000000000000
--- a/clang/test/Sema/loongarch-attr-model.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: %clang_cc1 -triple loongarch64 -verify -fsyntax-only %s
-
-#if !__has_attribute(model)
-#error "Should support model attribute"
-#endif
-
-int a __attribute((model("tiny"))); // expected-error {{code_model 'tiny' is not yet supported on this target}}
-int b __attribute((model("small"))); // expected-error {{code_model 'small' is not yet supported on this target}}
-int c __attribute((model("normal"))); // no-warning
-int d __attribute((model("kernel"))); // expected-error {{code_model 'kernel' is not yet supported on this target}}
-int e __attribute((model("medium"))); // no-warning
-int f __attribute((model("large"))); // expected-error {{code_model 'large' is not yet supported on this target}}
-int g __attribute((model("extreme"))); // no-warning

>From 5ecaf78acd8c835df03983385a4b49f50d1237bc Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Wed, 6 Dec 2023 09:57:42 +0800
Subject: [PATCH 4/6] Address  aeubanks's comments

---
 clang/include/clang/Basic/AttrDocs.td | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index c3c3d92e7367cd..428de4cfdbafea 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -60,9 +60,8 @@ global variable or function should be in after translation.
 def CodeModelDocs : Documentation {
   let Category = DocCatVariable;
   let Content = [{
-The ``model`` attribute allows you to use a different code model for
-addressing this variable, than the code model specified by the global
-``-mcmodel`` option.
+The ``model`` attribute allows overriding the translation unit's
+code model (specified by ``-mcmodel``) for a specific global variable.
   }];
   let Heading = "model";
 }

>From d7070a55e132af08ab0b28b88896b202cab661a6 Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Thu, 7 Dec 2023 15:47:10 +0800
Subject: [PATCH 5/6] Address MaskRay's comments

---
 clang/test/CodeGen/LoongArch/attributes.c   | 10 ------
 clang/test/CodeGen/LoongArch/attributes.cpp | 37 +++++++++++++++++++++
 clang/test/Sema/attr-model.c                |  4 +--
 3 files changed, 38 insertions(+), 13 deletions(-)
 delete mode 100644 clang/test/CodeGen/LoongArch/attributes.c
 create mode 100644 clang/test/CodeGen/LoongArch/attributes.cpp

diff --git a/clang/test/CodeGen/LoongArch/attributes.c b/clang/test/CodeGen/LoongArch/attributes.c
deleted file mode 100644
index a6d086845e29b0..00000000000000
--- a/clang/test/CodeGen/LoongArch/attributes.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm -triple loongarch64 %s -o - | FileCheck %s
-
-// CHECK: @normal ={{.*}} global i32 0, code_model "small"
-int normal __attribute__((model("normal")));
-
-// CHECK: @medium ={{.*}} global i32 0, code_model "medium"
-int medium __attribute__((model("medium")));
-
-// CHECK: @extreme ={{.*}} global i32 0, code_model "large"
-int extreme __attribute__((model("extreme")));
diff --git a/clang/test/CodeGen/LoongArch/attributes.cpp b/clang/test/CodeGen/LoongArch/attributes.cpp
new file mode 100644
index 00000000000000..ff5ee762deca3f
--- /dev/null
+++ b/clang/test/CodeGen/LoongArch/attributes.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -emit-llvm -triple loongarch64 %s -o - | FileCheck %s
+
+// CHECK: @_ZL2v1 ={{.*}} global i32 0, code_model "small"
+static int v1 __attribute__((model("normal")));
+
+void use1() {
+  v1 = 1;
+}
+
+// CHECK: @v2 ={{.*}} global i32 0, code_model "medium"
+int v2 __attribute__((model("medium")));
+
+// CHECK: @v3 ={{.*}} global float 0.000000e+00, code_model "large"
+float v3 __attribute__((model("extreme")));
+
+// CHECK: @_ZL2v4IiE ={{.*}} global i32 0, code_model "medium"
+template <typename T>
+static T v4 __attribute__((model("medium")));
+
+void use2() {
+  v4<int> = 1;
+}
+
+// CHECK: @v5 ={{.*}} global i32 0, code_model "large"
+thread_local int v5 __attribute__((model("extreme")));
+
+struct S {
+  double d;
+};
+
+// CHECK: @v6 ={{.*}} global {{.*}}, code_model "medium"
+S v6 __attribute__((model("medium")));
+
+typedef void (*F)();
+
+// CHECK: @v7 ={{.*}} global ptr null, code_model "large"
+F v7 __attribute__((model("extreme")));
diff --git a/clang/test/Sema/attr-model.c b/clang/test/Sema/attr-model.c
index 770d7d91441125..42dc310a8fdd4b 100644
--- a/clang/test/Sema/attr-model.c
+++ b/clang/test/Sema/attr-model.c
@@ -12,22 +12,20 @@
 int a __attribute((model("tiny")));    // expected-error {{code_model 'tiny' is not yet supported on this target}}
 int b __attribute((model("small")));   // expected-error {{code_model 'small' is not yet supported on this target}}
 int c __attribute((model("normal")));  // aarch64-error {{code_model 'normal' is not yet supported on this target}} \
-                                       // loongarch-no-warning \
                                        // mips64-error {{code_model 'normal' is not yet supported on this target}} \
                                        // powerpc64-error {{code_model 'normal' is not yet supported on this target}} \
                                        // riscv64-error {{code_model 'normal' is not yet supported on this target}} \
                                        // x86_64-error {{code_model 'normal' is not yet supported on this target}}
 int d __attribute((model("kernel")));  // expected-error {{code_model 'kernel' is not yet supported on this target}}
 int e __attribute((model("medium")));  // aarch64-error {{code_model 'medium' is not yet supported on this target}} \
-                                       // loongarch-no-warning \
                                        // mips64-error {{code_model 'medium' is not yet supported on this target}} \
                                        // powerpc64-error {{code_model 'medium' is not yet supported on this target}} \
                                        // riscv64-error {{code_model 'medium' is not yet supported on this target}} \
                                        // x86_64-error {{code_model 'medium' is not yet supported on this target}}
 int f __attribute((model("large")));   // expected-error {{code_model 'large' is not yet supported on this target}}
 int g __attribute((model("extreme"))); // aarch64-error {{code_model 'extreme' is not yet supported on this target}} \
-                                       // loongarch64-no-warning \
                                        // mips64-error {{code_model 'extreme' is not yet supported on this target}} \
                                        // powerpc64-error {{code_model 'extreme' is not yet supported on this target}} \
                                        // riscv64-error {{code_model 'extreme' is not yet supported on this target}} \
                                        // x86_64-error {{code_model 'extreme' is not yet supported on this target}}
+void __attribute((model("extreme"))) h() {} // expected-error {{'model' attribute only applies to global variables}}

>From 157e5c8aa8cd2bbbe62e4cd9f07a18dff04098a8 Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Tue, 12 Dec 2023 15:45:00 -0600
Subject: [PATCH 6/6] Address MaskRay's comments

---
 clang/include/clang/Basic/Attr.td              |  8 ++++++--
 clang/lib/CodeGen/CodeGenModule.cpp            | 18 ++++++++----------
 clang/test/CodeGen/LoongArch/attributes.cpp    | 11 ++++-------
 ...ma-attribute-supported-attributes-list.test |  1 -
 .../test/Sema/{attr-model.c => attr-model.cpp} |  3 ++-
 5 files changed, 20 insertions(+), 21 deletions(-)
 rename clang/test/Sema/{attr-model.c => attr-model.cpp} (93%)

diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index d5b5717f3d77cb..9c0a24321af3ed 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -143,6 +143,11 @@ def ExternalGlobalVar : SubsetSubject<Var,
                                !S->isLocalExternDecl()}],
                              "external global variables">;
 
+def NonTLSGlobalVar : SubsetSubject<Var,
+                             [{S->hasGlobalStorage() &&
+                               S->getTLSKind() == 0}],
+                             "non-TLS global variables">;
+
 def InlineFunction : SubsetSubject<Function,
                              [{S->isInlineSpecified()}], "inline functions">;
 
@@ -2721,8 +2726,7 @@ def PragmaClangTextSection : InheritableAttr {
 def CodeModel : InheritableAttr {
   let Spellings = [GCC<"model">];
   let Args = [StringArgument<"Model">];
-  let Subjects =
-      SubjectList<[ GlobalVar ], ErrorDiag>;
+  let Subjects = SubjectList<[NonTLSGlobalVar], ErrorDiag>;
   let Documentation = [CodeModelDocs];
 }
 
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 1f49721e79ddc4..978f609f88be82 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -4842,16 +4842,14 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty,
       GV->setSection(".cp.rodata");
 
     // Handle code model attribute
-    if (D->hasAttr<CodeModelAttr>()) {
-      if (const CodeModelAttr *CMA = D->getAttr<CodeModelAttr>()) {
-        auto CM = llvm::StringSwitch<llvm::CodeModel::Model>(CMA->getModel())
-                      .Case("tiny", llvm::CodeModel::Tiny)
-                      .Case("kernel", llvm::CodeModel::Kernel)
-                      .Case("medium", llvm::CodeModel::Medium)
-                      .Case("large", llvm::CodeModel::Large)
-                      .Default(llvm::CodeModel::Small);
-        GV->setCodeModel(CM);
-      }
+    if (const auto *CMA = D->getAttr<CodeModelAttr>()) {
+      auto CM = llvm::StringSwitch<llvm::CodeModel::Model>(CMA->getModel())
+                    .Case("tiny", llvm::CodeModel::Tiny)
+                    .Case("kernel", llvm::CodeModel::Kernel)
+                    .Case("medium", llvm::CodeModel::Medium)
+                    .Case("large", llvm::CodeModel::Large)
+                    .Default(llvm::CodeModel::Small);
+      GV->setCodeModel(CM);
     }
 
     // Check if we a have a const declaration with an initializer, we may be
diff --git a/clang/test/CodeGen/LoongArch/attributes.cpp b/clang/test/CodeGen/LoongArch/attributes.cpp
index ff5ee762deca3f..fb700ad305012b 100644
--- a/clang/test/CodeGen/LoongArch/attributes.cpp
+++ b/clang/test/CodeGen/LoongArch/attributes.cpp
@@ -21,17 +21,14 @@ void use2() {
   v4<int> = 1;
 }
 
-// CHECK: @v5 ={{.*}} global i32 0, code_model "large"
-thread_local int v5 __attribute__((model("extreme")));
-
 struct S {
   double d;
 };
 
-// CHECK: @v6 ={{.*}} global {{.*}}, code_model "medium"
-S v6 __attribute__((model("medium")));
+// CHECK: @v5 ={{.*}} global {{.*}}, code_model "medium"
+S v5 __attribute__((model("medium")));
 
 typedef void (*F)();
 
-// CHECK: @v7 ={{.*}} global ptr null, code_model "large"
-F v7 __attribute__((model("extreme")));
+// CHECK: @v6 ={{.*}} global ptr null, code_model "large"
+F v6 __attribute__((model("extreme")));
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 2b191abdac8b56..dd91f4f88ad685 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -48,7 +48,6 @@
 // CHECK-NEXT: CarriesDependency (SubjectMatchRule_variable_is_parameter, SubjectMatchRule_objc_method, SubjectMatchRule_function)
 // CHECK-NEXT: Cleanup (SubjectMatchRule_variable_is_local)
 // CHECK-NEXT: CmseNSEntry (SubjectMatchRule_function)
-// CHECK-NEXT: CodeModel (SubjectMatchRule_variable_is_global)
 // CHECK-NEXT: Cold (SubjectMatchRule_function)
 // CHECK-NEXT: Common (SubjectMatchRule_variable)
 // CHECK-NEXT: ConstInit (SubjectMatchRule_variable_is_global)
diff --git a/clang/test/Sema/attr-model.c b/clang/test/Sema/attr-model.cpp
similarity index 93%
rename from clang/test/Sema/attr-model.c
rename to clang/test/Sema/attr-model.cpp
index 42dc310a8fdd4b..78090dd5fc8a57 100644
--- a/clang/test/Sema/attr-model.c
+++ b/clang/test/Sema/attr-model.cpp
@@ -28,4 +28,5 @@ int g __attribute((model("extreme"))); // aarch64-error {{code_model 'extreme' i
                                        // powerpc64-error {{code_model 'extreme' is not yet supported on this target}} \
                                        // riscv64-error {{code_model 'extreme' is not yet supported on this target}} \
                                        // x86_64-error {{code_model 'extreme' is not yet supported on this target}}
-void __attribute((model("extreme"))) h() {} // expected-error {{'model' attribute only applies to global variables}}
+void __attribute((model("extreme"))) h() {} // expected-error {{'model' attribute only applies to non-TLS global variables}}
+thread_local int i __attribute((model("extreme"))); // expected-error {{'model' attribute only applies to non-TLS global variables}}



More information about the cfe-commits mailing list