https://github.com/aeubanks updated https://github.com/llvm/llvm-project/pull/124834
>From 7c40169ec7430ec64aaeb053e423eca1ceff7f0d Mon Sep 17 00:00:00 2001 From: Arthur Eubanks <aeuba...@google.com> Date: Tue, 28 Jan 2025 20:36:58 +0000 Subject: [PATCH 1/9] [clang][X86] Support __attribute__((model("small"/"large"))) Following up #72078, on x86-64 this allows a global to be considered small or large regardless of the code model. For example, x86-64's medium code model by default classifies globals as small or large depending on their size relative to -mlarge-data-threshold. --- clang/docs/ReleaseNotes.rst | 5 +++++ clang/include/clang/Basic/Attr.td | 13 +++++++++---- clang/lib/Sema/SemaDeclAttr.cpp | 11 ++++++++++- clang/test/CodeGen/X86/codemodel.cpp | 27 +++++++++++++++++++++++++++ clang/test/Sema/attr-model.cpp | 22 ++++++++++------------ 5 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 clang/test/CodeGen/X86/codemodel.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7b5562a80a35a..dba3ed593dae2 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -657,6 +657,11 @@ Attribute Changes in Clang - Clang now disallows the use of attributes after the namespace name. (#GH121407) +- Clang now allows ``__attribute__((model("small")))`` and + ``__attribute__((model("large")))`` on non-TLS globals in x86-64 compilations. + This forces the global to be considered small or large in regards to the + x86-64 code model, regardless of the code model specified for the compilation. + Improvements to Clang's diagnostics ----------------------------------- diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index f4ba2bc3c6de3..092dc751d79f2 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -462,6 +462,7 @@ def TargetMSP430 : TargetArch<["msp430"]>; def TargetM68k : TargetArch<["m68k"]>; def TargetRISCV : TargetArch<["riscv32", "riscv64"]>; def TargetX86 : TargetArch<["x86"]>; +def TargetX86_64 : TargetArch<["x86_64"]>; def TargetAnyX86 : TargetArch<["x86", "x86_64"]>; def TargetWebAssembly : TargetArch<["wasm32", "wasm64"]>; def TargetNVPTX : TargetArch<["nvptx", "nvptx64"]>; @@ -3117,11 +3118,15 @@ def PragmaClangTextSection : InheritableAttr { let Documentation = [InternalOnly]; } -def CodeModel : InheritableAttr, TargetSpecificAttr<TargetLoongArch> { +def CodeModel : InheritableAttr, + TargetSpecificAttr<TargetArch<!listconcat( + TargetLoongArch.Arches, TargetX86_64.Arches)>> { let Spellings = [GCC<"model">]; - let Args = [EnumArgument<"Model", "llvm::CodeModel::Model", /*is_string=*/1, - ["normal", "medium", "extreme"], ["Small", "Medium", "Large"], - /*opt=*/0, /*fake=*/0, /*isExternalType=*/1, /*isCovered=*/0>]; + let Args = [EnumArgument< + "Model", "llvm::CodeModel::Model", + /*is_string=*/1, ["small", "normal", "medium", "large", "extreme"], + ["Small", "Small", "Medium", "Large", "Large"], + /*opt=*/0, /*fake=*/0, /*isExternalType=*/1, /*isCovered=*/0>]; let Subjects = SubjectList<[NonTLSGlobalVar], ErrorDiag>; let Documentation = [CodeModelDocs]; } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 9d7d22590bce4..e2c752df06c25 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -64,6 +64,7 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Triple.h" @@ -2949,6 +2950,13 @@ static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } } +static bool isValidCodeModelAttr(Sema &S, StringRef Str) { + bool IsX8664Target = + S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86_64; + bool IsX8664Spelling = Str == "small" || Str == "large"; + return IsX8664Target == IsX8664Spelling; +} + static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) { StringRef Str; SourceLocation LiteralLoc; @@ -2957,7 +2965,8 @@ static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) { return; llvm::CodeModel::Model CM; - if (!CodeModelAttr::ConvertStrToModel(Str, CM)) { + if (!CodeModelAttr::ConvertStrToModel(Str, CM) || + !isValidCodeModelAttr(S, Str)) { S.Diag(LiteralLoc, diag::err_attr_codemodel_arg) << Str; return; } diff --git a/clang/test/CodeGen/X86/codemodel.cpp b/clang/test/CodeGen/X86/codemodel.cpp new file mode 100644 index 0000000000000..60a840665b49c --- /dev/null +++ b/clang/test/CodeGen/X86/codemodel.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown %s -o - | FileCheck %s + +// CHECK: @_ZL2v1 ={{.*}} global i32 0, code_model "small" +static int v1 __attribute__((model("small"))); + +void use1() { + v1 = 1; +} + +// CHECK: @v2 ={{.*}} global float 0.000000e+00, code_model "large" +float v2 __attribute__((model("large"))); + +// CHECK: @_ZL2v3IiE ={{.*}} global i32 0, code_model "small" +template <typename T> +static T v3 __attribute__((model("small"))); + +void use2() { + v3<int> = 1; +} +struct S { + double d; +}; + +typedef void (*F)(); + +// CHECK: @v4 ={{.*}} global ptr null, code_model "large" +F v4 __attribute__((model("large"))); diff --git a/clang/test/Sema/attr-model.cpp b/clang/test/Sema/attr-model.cpp index 898cc03939843..725ec502df396 100644 --- a/clang/test/Sema/attr-model.cpp +++ b/clang/test/Sema/attr-model.cpp @@ -5,7 +5,7 @@ // 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 defined(__loongarch__) && !__has_attribute(model) +#if (defined(__loongarch__) || defined(__x86_64__)) && !__has_attribute(model) #error "Should support model attribute" #endif @@ -14,51 +14,49 @@ int a __attribute((model("tiny"))); // aarch64-warning {{unknown attribute 'm // mips64-warning {{unknown attribute 'model' ignored}} \ // powerpc64-warning {{unknown attribute 'model' ignored}} \ // riscv64-warning {{unknown attribute 'model' ignored}} \ - // x86_64-warning {{unknown attribute 'model' ignored}} + // x86_64-error {{code model 'tiny' is not supported on this target}} int b __attribute((model("small"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ // loongarch64-error {{code model 'small' is not supported on this target}} \ // mips64-warning {{unknown attribute 'model' ignored}} \ // powerpc64-warning {{unknown attribute 'model' ignored}} \ - // riscv64-warning {{unknown attribute 'model' ignored}} \ - // x86_64-warning {{unknown attribute 'model' ignored}} + // riscv64-warning {{unknown attribute 'model' ignored}} int c __attribute((model("normal"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ // mips64-warning {{unknown attribute 'model' ignored}} \ // powerpc64-warning {{unknown attribute 'model' ignored}} \ // riscv64-warning {{unknown attribute 'model' ignored}} \ - // x86_64-warning {{unknown attribute 'model' ignored}} + // x86_64-error {{code model 'normal' is not supported on this target}} int d __attribute((model("kernel"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ // loongarch64-error {{code model 'kernel' is not supported on this target}} \ // mips64-warning {{unknown attribute 'model' ignored}} \ // powerpc64-warning {{unknown attribute 'model' ignored}} \ // riscv64-warning {{unknown attribute 'model' ignored}} \ - // x86_64-warning {{unknown attribute 'model' ignored}} + // x86_64-error {{code model 'kernel' is not supported on this target}} int e __attribute((model("medium"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ // mips64-warning {{unknown attribute 'model' ignored}} \ // powerpc64-warning {{unknown attribute 'model' ignored}} \ // riscv64-warning {{unknown attribute 'model' ignored}} \ - // x86_64-warning {{unknown attribute 'model' ignored}} + // x86_64-error {{code model 'medium' is not supported on this target}} int f __attribute((model("large"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ // loongarch64-error {{code model 'large' is not supported on this target}} \ // mips64-warning {{unknown attribute 'model' ignored}} \ // powerpc64-warning {{unknown attribute 'model' ignored}} \ - // riscv64-warning {{unknown attribute 'model' ignored}} \ - // x86_64-warning {{unknown attribute 'model' ignored}} + // riscv64-warning {{unknown attribute 'model' ignored}} int g __attribute((model("extreme"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ // mips64-warning {{unknown attribute 'model' ignored}} \ // powerpc64-warning {{unknown attribute 'model' ignored}} \ // riscv64-warning {{unknown attribute 'model' ignored}} \ - // x86_64-warning {{unknown attribute 'model' ignored}} + // x86_64-error {{code model 'extreme' is not supported on this target}} void __attribute((model("extreme"))) h() {} // aarch64-warning {{unknown attribute 'model' ignored}} \ // loongarch64-error {{'model' attribute only applies to non-TLS global variables}} \ // mips64-warning {{unknown attribute 'model' ignored}} \ // powerpc64-warning {{unknown attribute 'model' ignored}} \ // riscv64-warning {{unknown attribute 'model' ignored}} \ - // x86_64-warning {{unknown attribute 'model' ignored}} + // x86_64-error {{'model' attribute only applies to non-TLS global variables}} thread_local int i __attribute((model("extreme"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ // loongarch64-error {{'model' attribute only applies to non-TLS global variables}} \ // mips64-warning {{unknown attribute 'model' ignored}} \ // powerpc64-warning {{unknown attribute 'model' ignored}} \ // riscv64-warning {{unknown attribute 'model' ignored}} \ - // x86_64-warning {{unknown attribute 'model' ignored}} + // x86_64-error {{'model' attribute only applies to non-TLS global variables}} >From 8aa6b3fd3a7c33b80e598fc13b08aafcf6eae66e Mon Sep 17 00:00:00 2001 From: Arthur Eubanks <aeuba...@google.com> Date: Wed, 29 Jan 2025 19:32:27 +0000 Subject: [PATCH 2/9] address comments --- clang/lib/Sema/SemaDeclAttr.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index e2c752df06c25..bb69d3226eb41 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -2951,10 +2951,14 @@ static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } static bool isValidCodeModelAttr(Sema &S, StringRef Str) { - bool IsX8664Target = - S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86_64; - bool IsX8664Spelling = Str == "small" || Str == "large"; - return IsX8664Target == IsX8664Spelling; + if (S.Context.getTargetInfo().getTriple().isLoongArch()) { + return Str == "normal" || Str == "medium" || Str == "extreme"; + } else { + assert(S.Context.getTargetInfo().getTriple().getArch() == + llvm::Triple::x86_64 && + "only loongarch/x86-64 supported"); + return Str == "small" || Str == "large"; + } } static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) { >From 2fdf2eed3ab3513ea30ee23354cf4a249087b323 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks <aeuba...@google.com> Date: Wed, 29 Jan 2025 20:55:54 +0000 Subject: [PATCH 3/9] add nvptx RUN line to test, refactor test --- clang/test/Sema/attr-model.cpp | 66 ++++++++++++---------------------- 1 file changed, 22 insertions(+), 44 deletions(-) diff --git a/clang/test/Sema/attr-model.cpp b/clang/test/Sema/attr-model.cpp index 725ec502df396..938e3857a859d 100644 --- a/clang/test/Sema/attr-model.cpp +++ b/clang/test/Sema/attr-model.cpp @@ -1,62 +1,40 @@ -// RUN: %clang_cc1 -triple aarch64 -verify=expected,aarch64 -fsyntax-only %s +// RUN: %clang_cc1 -triple aarch64 -verify=expected,unsupported -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 mips64 -verify=expected,unsupported -fsyntax-only %s +// RUN: %clang_cc1 -triple powerpc64 -verify=expected,unsupported -fsyntax-only %s +// RUN: %clang_cc1 -triple riscv64 -verify=expected,unsupported -fsyntax-only %s // RUN: %clang_cc1 -triple x86_64 -verify=expected,x86_64 -fsyntax-only %s +// RUN: %clang_cc1 -triple nvptx64 -fcuda-is-device -verify=expected,unsupported -fsyntax-only %s #if (defined(__loongarch__) || defined(__x86_64__)) && !__has_attribute(model) #error "Should support model attribute" #endif -int a __attribute((model("tiny"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ +int a __attribute((model("tiny"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ // loongarch64-error {{code model 'tiny' is not supported on this target}} \ - // mips64-warning {{unknown attribute 'model' ignored}} \ - // powerpc64-warning {{unknown attribute 'model' ignored}} \ - // riscv64-warning {{unknown attribute 'model' ignored}} \ // x86_64-error {{code model 'tiny' is not supported on this target}} -int b __attribute((model("small"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ - // loongarch64-error {{code model 'small' is not supported on this target}} \ - // mips64-warning {{unknown attribute 'model' ignored}} \ - // powerpc64-warning {{unknown attribute 'model' ignored}} \ - // riscv64-warning {{unknown attribute 'model' ignored}} -int c __attribute((model("normal"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ - // mips64-warning {{unknown attribute 'model' ignored}} \ - // powerpc64-warning {{unknown attribute 'model' ignored}} \ - // riscv64-warning {{unknown attribute 'model' ignored}} \ +int b __attribute((model("small"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ + // loongarch64-error {{code model 'small' is not supported on this target}} +int c __attribute((model("normal"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ // x86_64-error {{code model 'normal' is not supported on this target}} -int d __attribute((model("kernel"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ +int d __attribute((model("kernel"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ // loongarch64-error {{code model 'kernel' is not supported on this target}} \ - // mips64-warning {{unknown attribute 'model' ignored}} \ - // powerpc64-warning {{unknown attribute 'model' ignored}} \ - // riscv64-warning {{unknown attribute 'model' ignored}} \ // x86_64-error {{code model 'kernel' is not supported on this target}} -int e __attribute((model("medium"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ - // mips64-warning {{unknown attribute 'model' ignored}} \ - // powerpc64-warning {{unknown attribute 'model' ignored}} \ - // riscv64-warning {{unknown attribute 'model' ignored}} \ +int e __attribute((model("medium"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ // x86_64-error {{code model 'medium' is not supported on this target}} -int f __attribute((model("large"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ - // loongarch64-error {{code model 'large' is not supported on this target}} \ - // mips64-warning {{unknown attribute 'model' ignored}} \ - // powerpc64-warning {{unknown attribute 'model' ignored}} \ - // riscv64-warning {{unknown attribute 'model' ignored}} -int g __attribute((model("extreme"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ - // mips64-warning {{unknown attribute 'model' ignored}} \ - // powerpc64-warning {{unknown attribute 'model' ignored}} \ - // riscv64-warning {{unknown attribute 'model' ignored}} \ +int f __attribute((model("large"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ + // loongarch64-error {{code model 'large' is not supported on this target}} +int g __attribute((model("extreme"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ // x86_64-error {{code model 'extreme' is not supported on this target}} -void __attribute((model("extreme"))) h() {} // aarch64-warning {{unknown attribute 'model' ignored}} \ +void __attribute((model("extreme"))) h() {} // unsupported-warning {{unknown attribute 'model' ignored}} \ // loongarch64-error {{'model' attribute only applies to non-TLS global variables}} \ - // mips64-warning {{unknown attribute 'model' ignored}} \ - // powerpc64-warning {{unknown attribute 'model' ignored}} \ - // riscv64-warning {{unknown attribute 'model' ignored}} \ // x86_64-error {{'model' attribute only applies to non-TLS global variables}} -thread_local int i __attribute((model("extreme"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ - // loongarch64-error {{'model' attribute only applies to non-TLS global variables}} \ - // mips64-warning {{unknown attribute 'model' ignored}} \ - // powerpc64-warning {{unknown attribute 'model' ignored}} \ - // riscv64-warning {{unknown attribute 'model' ignored}} \ - // x86_64-error {{'model' attribute only applies to non-TLS global variables}} +// NVPTX doesn't support thread_local at all. +#ifndef __NVPTX__ +thread_local +#endif +int i __attribute((model("extreme"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ + // loongarch64-error {{'model' attribute only applies to non-TLS global variables}} \ + // x86_64-error {{'model' attribute only applies to non-TLS global variables}} >From 1a32c3106f7732c78f482b77129e8fa8ef0804bb Mon Sep 17 00:00:00 2001 From: Arthur Eubanks <aeuba...@google.com> Date: Wed, 29 Jan 2025 21:24:59 +0000 Subject: [PATCH 4/9] add more flags to RUN line --- clang/test/Sema/attr-model.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Sema/attr-model.cpp b/clang/test/Sema/attr-model.cpp index 938e3857a859d..37a0152ca8e46 100644 --- a/clang/test/Sema/attr-model.cpp +++ b/clang/test/Sema/attr-model.cpp @@ -4,7 +4,7 @@ // RUN: %clang_cc1 -triple powerpc64 -verify=expected,unsupported -fsyntax-only %s // RUN: %clang_cc1 -triple riscv64 -verify=expected,unsupported -fsyntax-only %s // RUN: %clang_cc1 -triple x86_64 -verify=expected,x86_64 -fsyntax-only %s -// RUN: %clang_cc1 -triple nvptx64 -fcuda-is-device -verify=expected,unsupported -fsyntax-only %s +// RUN: %clang_cc1 -triple nvptx64-unknown-cuda -fcuda-is-device -x cuda -verify=expected,unsupported -fsyntax-only %s #if (defined(__loongarch__) || defined(__x86_64__)) && !__has_attribute(model) #error "Should support model attribute" >From 7ce06bdfc776eb3d8492da3042c4a05248425a78 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks <aeuba...@google.com> Date: Mon, 3 Feb 2025 20:36:13 +0000 Subject: [PATCH 5/9] allow and ignore attribute on nvptx compiles --- clang/include/clang/Basic/Attr.td | 10 +++++++--- clang/lib/Sema/SemaDeclAttr.cpp | 5 +++++ clang/test/Sema/attr-model.cpp | 15 ++++++++------- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 092dc751d79f2..d411842e6376e 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3118,9 +3118,13 @@ def PragmaClangTextSection : InheritableAttr { let Documentation = [InternalOnly]; } -def CodeModel : InheritableAttr, - TargetSpecificAttr<TargetArch<!listconcat( - TargetLoongArch.Arches, TargetX86_64.Arches)>> { +// The code model attribute only applies to LoongArch and x86-64, but for NVPTX +// compilations that share code with the host, we want to ignore the attribute +// rather than warn on it. +def CodeModel + : InheritableAttr, + TargetSpecificAttr<TargetArch<!listconcat( + TargetLoongArch.Arches, TargetX86_64.Arches, TargetNVPTX.Arches)>> { let Spellings = [GCC<"model">]; let Args = [EnumArgument< "Model", "llvm::CodeModel::Model", diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index bb69d3226eb41..1237ee4d70854 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -2968,6 +2968,11 @@ static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) { if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc)) return; + // Ignore the attribute for NVPTX compiles since it only applies to host + // globals. + if (S.Context.getTargetInfo().getTriple().isNVPTX()) + return; + llvm::CodeModel::Model CM; if (!CodeModelAttr::ConvertStrToModel(Str, CM) || !isValidCodeModelAttr(S, Str)) { diff --git a/clang/test/Sema/attr-model.cpp b/clang/test/Sema/attr-model.cpp index 37a0152ca8e46..fcd06f294ef81 100644 --- a/clang/test/Sema/attr-model.cpp +++ b/clang/test/Sema/attr-model.cpp @@ -1,10 +1,10 @@ -// RUN: %clang_cc1 -triple aarch64 -verify=expected,unsupported -fsyntax-only %s -// RUN: %clang_cc1 -triple loongarch64 -verify=expected,loongarch64 -fsyntax-only %s -// RUN: %clang_cc1 -triple mips64 -verify=expected,unsupported -fsyntax-only %s -// RUN: %clang_cc1 -triple powerpc64 -verify=expected,unsupported -fsyntax-only %s -// RUN: %clang_cc1 -triple riscv64 -verify=expected,unsupported -fsyntax-only %s -// RUN: %clang_cc1 -triple x86_64 -verify=expected,x86_64 -fsyntax-only %s -// RUN: %clang_cc1 -triple nvptx64-unknown-cuda -fcuda-is-device -x cuda -verify=expected,unsupported -fsyntax-only %s +// RUN: %clang_cc1 -triple aarch64 -verify=unsupported -fsyntax-only %s +// RUN: %clang_cc1 -triple loongarch64 -verify=loongarch64 -fsyntax-only %s +// RUN: %clang_cc1 -triple mips64 -verify=unsupported -fsyntax-only %s +// RUN: %clang_cc1 -triple powerpc64 -verify=unsupported -fsyntax-only %s +// RUN: %clang_cc1 -triple riscv64 -verify=unsupported -fsyntax-only %s +// RUN: %clang_cc1 -triple x86_64 -verify=x86_64 -fsyntax-only %s +// RUN: %clang_cc1 -triple nvptx64-unknown-cuda -fcuda-is-device -x cuda -verify=ignored -fsyntax-only %s #if (defined(__loongarch__) || defined(__x86_64__)) && !__has_attribute(model) #error "Should support model attribute" @@ -28,6 +28,7 @@ int g __attribute((model("extreme"))); // unsupported-warning {{unknown attribut // x86_64-error {{code model 'extreme' is not supported on this target}} void __attribute((model("extreme"))) h() {} // unsupported-warning {{unknown attribute 'model' ignored}} \ + // ignored-error {{'model' attribute only applies to non-TLS global variables}} \ // loongarch64-error {{'model' attribute only applies to non-TLS global variables}} \ // x86_64-error {{'model' attribute only applies to non-TLS global variables}} >From 677970567ad179e4d0c49ffccf6fabaffafcee38 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks <aeuba...@google.com> Date: Tue, 4 Feb 2025 23:22:07 +0000 Subject: [PATCH 6/9] ignore amdgpu/spirv --- clang/include/clang/Basic/Attr.td | 5 ++++- clang/lib/Sema/SemaDeclAttr.cpp | 6 ++++-- clang/test/Sema/attr-model.cpp | 7 ++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 01c60044526a9..eadbcdd72cb20 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -452,6 +452,7 @@ class TargetArch<list<string> arches> : TargetSpec { } def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>; def TargetAArch64 : TargetArch<["aarch64", "aarch64_be", "aarch64_32"]>; +def TargetAMDGPU : TargetArch<["amdgcn", "r600"]>; def TargetAnyArm : TargetArch<!listconcat(TargetARM.Arches, TargetAArch64.Arches)>; def TargetAVR : TargetArch<["avr"]>; def TargetBPF : TargetArch<["bpfel", "bpfeb"]>; @@ -464,6 +465,7 @@ def TargetRISCV : TargetArch<["riscv32", "riscv64"]>; def TargetX86 : TargetArch<["x86"]>; def TargetX86_64 : TargetArch<["x86_64"]>; def TargetAnyX86 : TargetArch<["x86", "x86_64"]>; +def TargetSPIRV : TargetArch<["spirv", "spirv32", "spirv64"]>; def TargetWebAssembly : TargetArch<["wasm32", "wasm64"]>; def TargetNVPTX : TargetArch<["nvptx", "nvptx64"]>; def TargetWindows : TargetSpec { @@ -3124,7 +3126,8 @@ def PragmaClangTextSection : InheritableAttr { def CodeModel : InheritableAttr, TargetSpecificAttr<TargetArch<!listconcat( - TargetLoongArch.Arches, TargetX86_64.Arches, TargetNVPTX.Arches)>> { + TargetLoongArch.Arches, TargetX86_64.Arches, TargetNVPTX.Arches, + TargetAMDGPU.Arches, TargetSPIRV.Arches)>> { let Spellings = [GCC<"model">]; let Args = [EnumArgument< "Model", "llvm::CodeModel::Model", diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 1237ee4d70854..84248733a482d 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -2968,9 +2968,11 @@ static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) { if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc)) return; - // Ignore the attribute for NVPTX compiles since it only applies to host + // Ignore the attribute for GPU device compiles since it only applies to host // globals. - if (S.Context.getTargetInfo().getTriple().isNVPTX()) + if (S.Context.getTargetInfo().getTriple().isNVPTX() || + S.Context.getTargetInfo().getTriple().isAMDGPU() || + S.Context.getTargetInfo().getTriple().isSPIRV()) return; llvm::CodeModel::Model CM; diff --git a/clang/test/Sema/attr-model.cpp b/clang/test/Sema/attr-model.cpp index fcd06f294ef81..d4b6f592e8d81 100644 --- a/clang/test/Sema/attr-model.cpp +++ b/clang/test/Sema/attr-model.cpp @@ -5,6 +5,11 @@ // RUN: %clang_cc1 -triple riscv64 -verify=unsupported -fsyntax-only %s // RUN: %clang_cc1 -triple x86_64 -verify=x86_64 -fsyntax-only %s // RUN: %clang_cc1 -triple nvptx64-unknown-cuda -fcuda-is-device -x cuda -verify=ignored -fsyntax-only %s +// RUN: %clang_cc1 -triple amdgcn -verify=ignored -fsyntax-only %s +// RUN: %clang_cc1 -triple r600 -verify=ignored -fsyntax-only %s +// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -verify=ignored -fsyntax-only %s +// RUN: %clang_cc1 -triple spirv32-unknown-unknown -verify=ignored -fsyntax-only %s +// RUN: %clang_cc1 -triple spirv64-unknown-unknown -verify=ignored -fsyntax-only %s #if (defined(__loongarch__) || defined(__x86_64__)) && !__has_attribute(model) #error "Should support model attribute" @@ -33,7 +38,7 @@ void __attribute((model("extreme"))) h() {} // unsupported-warning {{unknown att // x86_64-error {{'model' attribute only applies to non-TLS global variables}} // NVPTX doesn't support thread_local at all. -#ifndef __NVPTX__ +#if !defined(__NVPTX__) && !defined(__AMDGCN__) && !defined(__R600__) && !defined(__SPIRV__) thread_local #endif int i __attribute((model("extreme"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ >From 2263db165f5b77810b7b631f352286bbdceed6f2 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks <aeuba...@google.com> Date: Wed, 5 Feb 2025 18:28:17 +0000 Subject: [PATCH 7/9] update AttrDocs.td --- clang/include/clang/Basic/AttrDocs.td | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index a8b588169725a..b609c5488cdce 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -62,6 +62,10 @@ def CodeModelDocs : Documentation { let Content = [{ The ``model`` attribute allows overriding the translation unit's code model (specified by ``-mcmodel``) for a specific global variable. + +On LoongArch, allowed values are "normal", "medium", "extreme". + +On x86-64, allowed values are "small" and "large". }]; let Heading = "model"; } >From bf8f7d41dda1d553ce69a24133c916f0cd4b41e9 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks <aeuba...@google.com> Date: Wed, 5 Feb 2025 21:14:34 +0000 Subject: [PATCH 8/9] more descriptive docs (at least for x86-64) --- clang/include/clang/Basic/AttrDocs.td | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index b609c5488cdce..a59d3a42cf8f1 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -65,7 +65,13 @@ code model (specified by ``-mcmodel``) for a specific global variable. On LoongArch, allowed values are "normal", "medium", "extreme". -On x86-64, allowed values are "small" and "large". +On x86-64, allowed values are ``"small"`` and ``"large"``. ``"small"`` is +roughly equivalent to ``-mcmodel=small``, meaning the global is considered +"small" placed closer to the ``.text`` section relative to "large" globals, and +to prefer using 32-bit relocations to access the global. ``"large"`` is roughly +equivalent to ``-mcmodel=large``, meaning the global is considered "large" and +placed further from the ``.text`` section relative to "small" globals, and +64-bit relocations must be used to access the global. }]; let Heading = "model"; } >From d314c8ebb83c21d960b53bc0b309aabfce914125 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks <aeuba...@google.com> Date: Wed, 12 Feb 2025 22:02:46 +0000 Subject: [PATCH 9/9] warn if host triple doesn't support attribute --- clang/lib/Sema/SemaDeclAttr.cpp | 35 ++++++++++++++++++------- clang/test/Sema/attr-model.cpp | 46 +++++++++++++++++++++++++-------- 2 files changed, 60 insertions(+), 21 deletions(-) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 84248733a482d..6632ed62605f3 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -2950,12 +2950,11 @@ static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } } -static bool isValidCodeModelAttr(Sema &S, StringRef Str) { - if (S.Context.getTargetInfo().getTriple().isLoongArch()) { +static bool isValidCodeModelAttr(llvm::Triple Triple, StringRef Str) { + if (Triple.isLoongArch()) { return Str == "normal" || Str == "medium" || Str == "extreme"; } else { - assert(S.Context.getTargetInfo().getTriple().getArch() == - llvm::Triple::x86_64 && + assert(Triple.getArch() == llvm::Triple::x86_64 && "only loongarch/x86-64 supported"); return Str == "small" || Str == "large"; } @@ -2964,20 +2963,36 @@ static bool isValidCodeModelAttr(Sema &S, StringRef Str) { static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) { StringRef Str; SourceLocation LiteralLoc; + auto IsTripleSupported = [](const llvm::Triple Triple) { + return Triple.getArch() == llvm::Triple::ArchType::x86_64 || + Triple.isLoongArch(); + }; + // Check that it is a string. if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc)) return; - // Ignore the attribute for GPU device compiles since it only applies to host - // globals. - if (S.Context.getTargetInfo().getTriple().isNVPTX() || - S.Context.getTargetInfo().getTriple().isAMDGPU() || - S.Context.getTargetInfo().getTriple().isSPIRV()) + SmallVector<llvm::Triple, 2> Triples = { + S.Context.getTargetInfo().getTriple()}; + if (auto *aux = S.Context.getAuxTargetInfo()) { + Triples.push_back(aux->getTriple()); + } else if (S.Context.getTargetInfo().getTriple().isNVPTX() || + S.Context.getTargetInfo().getTriple().isAMDGPU() || + S.Context.getTargetInfo().getTriple().isSPIRV()) { + // Ignore the attribute for pure GPU device compiles since it only applies + // to host globals. + return; + } + + auto SupportedTripleIt = llvm::find_if(Triples, IsTripleSupported); + if (SupportedTripleIt == Triples.end()) { + S.Diag(LiteralLoc, diag::warn_unknown_attribute_ignored) << AL; return; + } llvm::CodeModel::Model CM; if (!CodeModelAttr::ConvertStrToModel(Str, CM) || - !isValidCodeModelAttr(S, Str)) { + !isValidCodeModelAttr(*SupportedTripleIt, Str)) { S.Diag(LiteralLoc, diag::err_attr_codemodel_arg) << Str; return; } diff --git a/clang/test/Sema/attr-model.cpp b/clang/test/Sema/attr-model.cpp index d4b6f592e8d81..558439cf8db0f 100644 --- a/clang/test/Sema/attr-model.cpp +++ b/clang/test/Sema/attr-model.cpp @@ -11,36 +11,60 @@ // RUN: %clang_cc1 -triple spirv32-unknown-unknown -verify=ignored -fsyntax-only %s // RUN: %clang_cc1 -triple spirv64-unknown-unknown -verify=ignored -fsyntax-only %s +// RUN: %clang_cc1 -triple x86_64 -aux-triple nvptx64 -x cuda -verify=x86_64 -fsyntax-only %s +// RUN: %clang_cc1 -triple nvptx64 -aux-triple x86_64 -x cuda -fcuda-is-device -verify=nvptx64-x86_64 -fsyntax-only %s +// RUN: %clang_cc1 -triple aarch64 -aux-triple nvptx64 -x cuda -verify=unsupported -fsyntax-only %s +// RUN: %clang_cc1 -triple nvptx64 -aux-triple aarch64 -x cuda -fcuda-is-device -verify=nvptx64-unsupported -fsyntax-only %s + #if (defined(__loongarch__) || defined(__x86_64__)) && !__has_attribute(model) #error "Should support model attribute" #endif int a __attribute((model("tiny"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ // loongarch64-error {{code model 'tiny' is not supported on this target}} \ - // x86_64-error {{code model 'tiny' is not supported on this target}} + // x86_64-error {{code model 'tiny' is not supported on this target}} \ + // nvptx64-unsupported-warning {{unknown attribute 'model' ignored}} \ + // nvptx64-x86_64-error {{code model 'tiny' is not supported on this target}} int b __attribute((model("small"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ - // loongarch64-error {{code model 'small' is not supported on this target}} + // loongarch64-error {{code model 'small' is not supported on this target}} \ + // nvptx64-unsupported-warning {{unknown attribute 'model' ignored}} int c __attribute((model("normal"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ - // x86_64-error {{code model 'normal' is not supported on this target}} + // x86_64-error {{code model 'normal' is not supported on this target}} \ + // nvptx64-unsupported-warning {{unknown attribute 'model' ignored}} \ + // nvptx64-x86_64-error {{code model 'normal' is not supported on this target}} int d __attribute((model("kernel"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ // loongarch64-error {{code model 'kernel' is not supported on this target}} \ - // x86_64-error {{code model 'kernel' is not supported on this target}} + // x86_64-error {{code model 'kernel' is not supported on this target}} \ + // nvptx64-unsupported-warning {{unknown attribute 'model' ignored}} \ + // nvptx64-x86_64-error {{code model 'kernel' is not supported on this target}} int e __attribute((model("medium"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ - // x86_64-error {{code model 'medium' is not supported on this target}} + // x86_64-error {{code model 'medium' is not supported on this target}} \ + // nvptx64-unsupported-warning {{unknown attribute 'model' ignored}} \ + // nvptx64-x86_64-error {{code model 'medium' is not supported on this target}} int f __attribute((model("large"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ - // loongarch64-error {{code model 'large' is not supported on this target}} + // loongarch64-error {{code model 'large' is not supported on this target}} \ + // nvptx64-unsupported-warning {{unknown attribute 'model' ignored}} int g __attribute((model("extreme"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ - // x86_64-error {{code model 'extreme' is not supported on this target}} + // x86_64-error {{code model 'extreme' is not supported on this target}} \ + // nvptx64-unsupported-warning {{unknown attribute 'model' ignored}} \ + // nvptx64-x86_64-error {{code model 'extreme' is not supported on this target}} void __attribute((model("extreme"))) h() {} // unsupported-warning {{unknown attribute 'model' ignored}} \ // ignored-error {{'model' attribute only applies to non-TLS global variables}} \ // loongarch64-error {{'model' attribute only applies to non-TLS global variables}} \ - // x86_64-error {{'model' attribute only applies to non-TLS global variables}} + // x86_64-error {{'model' attribute only applies to non-TLS global variables}} \ + // nvptx64-unsupported-error {{'model' attribute only applies to non-TLS global variables}} \ + // nvptx64-x86_64-error {{'model' attribute only applies to non-TLS global variables}} -// NVPTX doesn't support thread_local at all. -#if !defined(__NVPTX__) && !defined(__AMDGCN__) && !defined(__R600__) && !defined(__SPIRV__) +#if !defined(__CUDA__) || !defined(__CUDA_ARCH__) +// if we are compiling for non-cuda host, or host mode in a CUDA compile +#if !defined(__AMDGCN__) && !defined(__R600__) && !defined(__SPIRV__) +// for all non-cuda hosts, above targets don't support thread_local thread_local #endif +#endif int i __attribute((model("extreme"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ // loongarch64-error {{'model' attribute only applies to non-TLS global variables}} \ - // x86_64-error {{'model' attribute only applies to non-TLS global variables}} + // x86_64-error {{'model' attribute only applies to non-TLS global variables}} \ + // nvptx64-unsupported-warning {{unknown attribute 'model' ignored}} \ + // nvptx64-x86_64-error {{code model 'extreme' is not supported on this target}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits