[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `llvm-clang-x86_64-gcc-ubuntu-no-asserts` running on `doug-worker-6` while building `clang,llvm` at step 6 "test-build-unified-tree-check-all". Full details are available at: https://lab.llvm.org/buildbot/#/builders/202/builds/1531 Here is the relevant piece of the build log for the reference ``` Step 6 (test-build-unified-tree-check-all) failure: test (failure) TEST 'Clang :: CodeGen/LoongArch/targetattr.c' FAILED Exit Code: 1 Command Output (stderr): -- /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/clang --target=loongarch64-linux-gnu /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/clang/test/CodeGen/LoongArch/targetattr.c -S -emit-llvm -o -| /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/FileCheck /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/clang/test/CodeGen/LoongArch/targetattr.c # RUN: at line 2 + /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/clang --target=loongarch64-linux-gnu /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/clang/test/CodeGen/LoongArch/targetattr.c -S -emit-llvm -o - + /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/FileCheck /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/clang/test/CodeGen/LoongArch/targetattr.c [1m/home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/clang/test/CodeGen/LoongArch/targetattr.c:8:16: [0m[0;1;31merror: [0m[1mCHECK-NEXT: is not on the line after the previous match [0m// CHECK-NEXT: [[ENTRY:.*:]] [0;1;32m ^ [0m[1m:11:1: [0m[0;1;30mnote: [0m[1m'next' match was here [0m; Function Attrs: noinline nounwind optnone [0;1;32m^ [0m[1m:7:40: [0m[0;1;30mnote: [0m[1mprevious match ended here [0mdefine dso_local void @testdiv32() #0 { [0;1;32m ^ [0m[1m:8:1: [0m[0;1;30mnote: [0m[1mnon-matching line after previous match is here [0m ret void [0;1;32m^ [0m[1m/home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/clang/test/CodeGen/LoongArch/targetattr.c:16:16: [0m[0;1;31merror: [0m[1mCHECK-NEXT: is not on the line after the previous match [0m// CHECK-NEXT: [[ENTRY:.*:]] [0;1;32m ^ [0m[1m:16:1: [0m[0;1;30mnote: [0m[1m'next' match was here [0m; Function Attrs: noinline nounwind optnone [0;1;32m^ [0m[1m:12:46: [0m[0;1;30mnote: [0m[1mprevious match ended here [0mdefine dso_local void @testLoongarch64() #1 { [0;1;32m ^ [0m[1m:13:1: [0m[0;1;30mnote: [0m[1mnon-matching line after previous match is here [0m ret void [0;1;32m^ [0m[1m/home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/clang/test/CodeGen/LoongArch/targetattr.c:24:16: [0m[0;1;31merror: [0m[1mCHECK-NEXT: is not on the line after the previous match [0m// CHECK-NEXT: [[ENTRY:.*:]] [0;1;32m ^ [0m[1m:21:1: [0m[0;1;30mnote: [0m[1m'next' match was here [0m; Function Attrs: noinline nounwind optnone [0;1;32m^ [0m[1m:17:42: [0m[0;1;30mnote: [0m[1mprevious match ended here [0mdefine dso_local void @testLa64v10() #1 { [0;1;32m ^ [0m[1m:18:1: [0m[0;1;30mnote: [0m[1mnon-matching line after previous match is here [0m ret void [0;1;32m^ [0m[1m/home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/clang/test/CodeGen/LoongArch/targetattr.c:32:16: [0m[0;1;31merror: [0m[1mCHECK-NEXT: is not on the line after the previous match [0m// CHECK-NEXT: [[ENTRY:.*:]] [0;1;32m ^ [0m[1m:26:1: [0m[0;1;30mnote: [0m[1m'next' match was here [0m; Function Attrs: noinline nounwind optnone [0;1;32m^ ... ``` https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `fuchsia-x86_64-linux` running on `fuchsia-debian-64-us-central1-a-1` while building `clang,llvm` at step 4 "annotate". Full details are available at: https://lab.llvm.org/buildbot/#/builders/11/builds/16173 Here is the relevant piece of the build log for the reference ``` Step 4 (annotate) failure: 'python ../llvm-zorg/zorg/buildbot/builders/annotated/fuchsia-linux.py ...' (failure) ... [849/1374] Running the Clang regression tests llvm-lit: /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using clang: /var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-ilqvuc8n/bin/clang llvm-lit: /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/llvm/utils/lit/lit/llvm/subst.py:126: note: Did not find cir-opt in /var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-ilqvuc8n/bin:/var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-ilqvuc8n/bin llvm-lit: /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/llvm/utils/lit/lit/llvm/subst.py:126: note: Did not find clang-repl in /var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-ilqvuc8n/bin:/var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-ilqvuc8n/bin llvm-lit: /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using ld.lld: /var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-ilqvuc8n/bin/ld.lld llvm-lit: /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using lld-link: /var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-ilqvuc8n/bin/lld-link llvm-lit: /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using ld64.lld: /var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-ilqvuc8n/bin/ld64.lld llvm-lit: /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using wasm-ld: /var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-ilqvuc8n/bin/wasm-ld -- Testing: 21544 tests, 60 workers -- Testing: 0.. 10. FAIL: Clang :: CodeGen/LoongArch/targetattr.c (3867 of 21544) TEST 'Clang :: CodeGen/LoongArch/targetattr.c' FAILED Exit Code: 1 Command Output (stderr): -- /var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-ilqvuc8n/bin/clang --target=loongarch64-linux-gnu /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/clang/test/CodeGen/LoongArch/targetattr.c -S -emit-llvm -o -| /var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-ilqvuc8n/bin/FileCheck /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/clang/test/CodeGen/LoongArch/targetattr.c # RUN: at line 2 + /var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-ilqvuc8n/bin/clang --target=loongarch64-linux-gnu /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/clang/test/CodeGen/LoongArch/targetattr.c -S -emit-llvm -o - + /var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-ilqvuc8n/bin/FileCheck /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/clang/test/CodeGen/LoongArch/targetattr.c /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/clang/test/CodeGen/LoongArch/targetattr.c:8:16: error: CHECK-NEXT: is not on the line after the previous match // CHECK-NEXT: [[ENTRY:.*:]] ^ :11:1: note: 'next' match was here ; Function Attrs: noinline nounwind optnone ^ :7:40: note: previous match ended here define dso_local void @testdiv32() #0 { ^ :8:1: note: non-matching line after previous match is here ret void ^ /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/clang/test/CodeGen/LoongArch/targetattr.c:16:16: error: CHECK-NEXT: is not on the line after the previous match // CHECK-NEXT: [[ENTRY:.*:]] ^ :16:1: note: 'next' match was here ; Function Attrs: noinline nounwind optnone ^ :12:46: note: previous match ended here define dso_local void @testLoongarch64() #1 { ^ :13:1: note: non-matching line after previous match is here ret void ^ /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/clang/test/CodeGen/LoongArch/targetattr.c:24:16: error: CHECK-NEXT: is not on the line after the previous match // CHECK-NEXT: [[ENTRY:.*:]] ^ :21:1: note: 'next' match was here ; Function Attrs: noinline nounwind optnone ^ Step 7 (check) failure: check (failure) ... [849/1374] Running the Clang regression tests llvm-lit: /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using clang: /var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-ilqvuc8n/bin/clang llvm-lit: /var/lib/buildbot/fuchsia-x86_64-linux/llvm-project/llvm/utils/lit/lit/llvm/subst.py:126: note: Did not find cir-opt in /var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-ilqvuc8n/bin:/var/lib/buildbot/fuchsia-x86_64-linux/build/llvm-build-ilqvuc8n/bin llvm-lit: /var/lib/bui
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
https://github.com/Ami-zhang closed https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -34,6 +34,19 @@ bool LoongArch::isValidArchName(StringRef Arch) { return false; } +bool LoongArch::isValidFeatureName(StringRef Feature) { + if (Feature.starts_with("+") || Feature.starts_with("-")) { +return false; + } wangleiat wrote: The braces can be omitted. https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
https://github.com/Ami-zhang updated https://github.com/llvm/llvm-project/pull/140700 >From 1f521b6105a032d4722041d179e96cee28ab4169 Mon Sep 17 00:00:00 2001 From: Ami-zhang Date: Wed, 14 May 2025 15:21:54 +0800 Subject: [PATCH 1/2] [Clang][LoongArch] Support target attribute for function This adds support under LoongArch for the target("..") attributes. The supported formats are: - "arch=" strings, that specify the architecture features for a function as per the -march=arch option. - "tune=" strings, that specify the tune-cpu cpu for a function as per -mtune. - "", "no-" enabled/disables the specific feature. --- clang/lib/Basic/Targets/LoongArch.cpp | 49 ++ clang/lib/Basic/Targets/LoongArch.h | 4 + clang/lib/Sema/SemaDeclAttr.cpp | 11 +++ clang/test/CodeGen/LoongArch/targetattr.c | 92 +++ clang/test/Sema/attr-target-loongarch.c | 25 + .../llvm/TargetParser/LoongArchTargetParser.h | 1 + .../TargetParser/LoongArchTargetParser.cpp| 12 +++ 7 files changed, 194 insertions(+) create mode 100644 clang/test/CodeGen/LoongArch/targetattr.c create mode 100644 clang/test/Sema/attr-target-loongarch.c diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp index ca742797d7a3b..aee273a76a608 100644 --- a/clang/lib/Basic/Targets/LoongArch.cpp +++ b/clang/lib/Basic/Targets/LoongArch.cpp @@ -388,6 +388,51 @@ bool LoongArchTargetInfo::handleTargetFeatures( return true; } +ParsedTargetAttr +LoongArchTargetInfo::parseTargetAttr(StringRef Features) const { + ParsedTargetAttr Ret; + if (Features == "default") +return Ret; + SmallVector AttrFeatures; + Features.split(AttrFeatures, ","); + + for (auto &Feature : AttrFeatures) { +Feature = Feature.trim(); + +if (Feature.starts_with("arch=")) { + StringRef ArchValue = Feature.split("=").second.trim(); + + if (llvm::LoongArch::isValidArchName(ArchValue) || + ArchValue == "la64v1.0" || ArchValue == "la64v1.1") { +std::vector ArchFeatures; +if (llvm::LoongArch::getArchFeatures(ArchValue, ArchFeatures)) { + Ret.Features.insert(Ret.Features.end(), ArchFeatures.begin(), + ArchFeatures.end()); +} + +if (!Ret.CPU.empty()) + Ret.Duplicate = "arch="; +else if (ArchValue == "la64v1.0" || ArchValue == "la64v1.1") + Ret.CPU = "loongarch64"; +else + Ret.CPU = ArchValue; + } else { +Ret.Features.push_back("!arch=" + ArchValue.str()); + } +} else if (Feature.starts_with("tune=")) { + if (!Ret.Tune.empty()) +Ret.Duplicate = "tune="; + else +Ret.Tune = Feature.split("=").second.trim(); +} else if (Feature.starts_with("no-")) { + Ret.Features.push_back("-" + Feature.split("-").second.str()); +} else { + Ret.Features.push_back("+" + Feature.str()); +} + } + return Ret; +} + bool LoongArchTargetInfo::isValidCPUName(StringRef Name) const { return llvm::LoongArch::isValidCPUName(Name); } @@ -396,3 +441,7 @@ void LoongArchTargetInfo::fillValidCPUList( SmallVectorImpl &Values) const { llvm::LoongArch::fillValidCPUList(Values); } + +bool LoongArchTargetInfo::isValidFeatureName(StringRef Name) const { + return llvm::LoongArch::isValidFeatureName(Name); +} diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h index 4c7b53abfef9b..a83bb925bc310 100644 --- a/clang/lib/Basic/Targets/LoongArch.h +++ b/clang/lib/Basic/Targets/LoongArch.h @@ -101,6 +101,9 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { bool handleTargetFeatures(std::vector &Features, DiagnosticsEngine &Diags) override; + ParsedTargetAttr parseTargetAttr(StringRef Str) const override; + bool supportsTargetAttributeTune() const override { return true; } + bool initFeatureMap(llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, @@ -110,6 +113,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { bool isValidCPUName(StringRef Name) const override; void fillValidCPUList(SmallVectorImpl &Values) const override; + bool isValidFeatureName(StringRef Name) const override; }; class LLVM_LIBRARY_VISIBILITY LoongArch32TargetInfo diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 4d7f0455444f1..8e44e2e44bb24 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3195,6 +3195,17 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) { } } + if (Context.getTargetInfo().getTriple().isLoongArch()) { +for (const auto &Feature : ParsedAttrs.Features) { + StringRef CurFeature = Feature; + if (CurFeature.starts_with("!arch=")) { +StringRef ArchValue = CurFeature.split("=").second.trim(); +return Diag(Lit
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -388,6 +388,76 @@ bool LoongArchTargetInfo::handleTargetFeatures( return true; } +enum class AttrFeatureKind { Arch, Tune, NoFeature, Feature, Invalid }; wangleiat wrote: Is Invalid unused? https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
https://github.com/wangleiat edited https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -34,6 +34,19 @@ bool LoongArch::isValidArchName(StringRef Arch) { return false; } +bool LoongArch::isValidFeatureName(StringRef Feature) { + if (Feature.starts_with("+") || Feature.starts_with("-")) { +return false; + } + for (const auto F : AllFeatures) { +StringRef CanonicalName = wangleiat wrote: Beware unnecessary copies. `auto &F` https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
https://github.com/wangleiat approved this pull request. LGTM with some minor nits, thanks. https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
https://github.com/wangleiat edited https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -3195,6 +3195,17 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) { } } + if (Context.getTargetInfo().getTriple().isLoongArch()) { +for (const auto &Feature : ParsedAttrs.Features) { + StringRef CurFeature = Feature; + if (CurFeature.starts_with("!arch=")) { wangleiat wrote: My mistake — I didn't notice the `!`. https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
https://github.com/Ami-zhang updated https://github.com/llvm/llvm-project/pull/140700 >From a9f8fa53dd260f8161a2762c5ec118722cbf22a1 Mon Sep 17 00:00:00 2001 From: Ami-zhang Date: Wed, 14 May 2025 15:21:54 +0800 Subject: [PATCH 1/2] [Clang][LoongArch] Support target attribute for function This adds support under LoongArch for the target("..") attributes. The supported formats are: - "arch=" strings, that specify the architecture features for a function as per the -march=arch option. - "tune=" strings, that specify the tune-cpu cpu for a function as per -mtune. - "", "no-" enabled/disables the specific feature. --- clang/lib/Basic/Targets/LoongArch.cpp | 49 ++ clang/lib/Basic/Targets/LoongArch.h | 4 + clang/lib/Sema/SemaDeclAttr.cpp | 11 +++ clang/test/CodeGen/LoongArch/targetattr.c | 92 +++ clang/test/Sema/attr-target-loongarch.c | 25 + .../llvm/TargetParser/LoongArchTargetParser.h | 1 + .../TargetParser/LoongArchTargetParser.cpp| 13 +++ 7 files changed, 195 insertions(+) create mode 100644 clang/test/CodeGen/LoongArch/targetattr.c create mode 100644 clang/test/Sema/attr-target-loongarch.c diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp index ca742797d7a3b..aee273a76a608 100644 --- a/clang/lib/Basic/Targets/LoongArch.cpp +++ b/clang/lib/Basic/Targets/LoongArch.cpp @@ -388,6 +388,51 @@ bool LoongArchTargetInfo::handleTargetFeatures( return true; } +ParsedTargetAttr +LoongArchTargetInfo::parseTargetAttr(StringRef Features) const { + ParsedTargetAttr Ret; + if (Features == "default") +return Ret; + SmallVector AttrFeatures; + Features.split(AttrFeatures, ","); + + for (auto &Feature : AttrFeatures) { +Feature = Feature.trim(); + +if (Feature.starts_with("arch=")) { + StringRef ArchValue = Feature.split("=").second.trim(); + + if (llvm::LoongArch::isValidArchName(ArchValue) || + ArchValue == "la64v1.0" || ArchValue == "la64v1.1") { +std::vector ArchFeatures; +if (llvm::LoongArch::getArchFeatures(ArchValue, ArchFeatures)) { + Ret.Features.insert(Ret.Features.end(), ArchFeatures.begin(), + ArchFeatures.end()); +} + +if (!Ret.CPU.empty()) + Ret.Duplicate = "arch="; +else if (ArchValue == "la64v1.0" || ArchValue == "la64v1.1") + Ret.CPU = "loongarch64"; +else + Ret.CPU = ArchValue; + } else { +Ret.Features.push_back("!arch=" + ArchValue.str()); + } +} else if (Feature.starts_with("tune=")) { + if (!Ret.Tune.empty()) +Ret.Duplicate = "tune="; + else +Ret.Tune = Feature.split("=").second.trim(); +} else if (Feature.starts_with("no-")) { + Ret.Features.push_back("-" + Feature.split("-").second.str()); +} else { + Ret.Features.push_back("+" + Feature.str()); +} + } + return Ret; +} + bool LoongArchTargetInfo::isValidCPUName(StringRef Name) const { return llvm::LoongArch::isValidCPUName(Name); } @@ -396,3 +441,7 @@ void LoongArchTargetInfo::fillValidCPUList( SmallVectorImpl &Values) const { llvm::LoongArch::fillValidCPUList(Values); } + +bool LoongArchTargetInfo::isValidFeatureName(StringRef Name) const { + return llvm::LoongArch::isValidFeatureName(Name); +} diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h index 4c7b53abfef9b..a83bb925bc310 100644 --- a/clang/lib/Basic/Targets/LoongArch.h +++ b/clang/lib/Basic/Targets/LoongArch.h @@ -101,6 +101,9 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { bool handleTargetFeatures(std::vector &Features, DiagnosticsEngine &Diags) override; + ParsedTargetAttr parseTargetAttr(StringRef Str) const override; + bool supportsTargetAttributeTune() const override { return true; } + bool initFeatureMap(llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, @@ -110,6 +113,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { bool isValidCPUName(StringRef Name) const override; void fillValidCPUList(SmallVectorImpl &Values) const override; + bool isValidFeatureName(StringRef Name) const override; }; class LLVM_LIBRARY_VISIBILITY LoongArch32TargetInfo diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 4d7f0455444f1..8e44e2e44bb24 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3195,6 +3195,17 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) { } } + if (Context.getTargetInfo().getTriple().isLoongArch()) { +for (const auto &Feature : ParsedAttrs.Features) { + StringRef CurFeature = Feature; + if (CurFeature.starts_with("!arch=")) { +StringRef ArchValue = CurFeature.split("=").second.trim(); +return Diag(Lit
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
https://github.com/Ami-zhang edited https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
https://github.com/Ami-zhang edited https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -388,6 +388,76 @@ bool LoongArchTargetInfo::handleTargetFeatures( return true; } +enum class AttrFeatureKind { Arch, Tune, NoFeature, Feature, Invalid }; + +static std::pair +getAttrFeatureTypeAndValue(llvm::StringRef AttrFeature) { + if (auto Split = AttrFeature.split("="); !Split.second.empty()) { +if (Split.first.trim() == "arch") + return {AttrFeatureKind::Arch, Split.second.trim()}; +if (Split.first.trim() == "tune") + return {AttrFeatureKind::Tune, Split.second.trim()}; + } + if (AttrFeature.starts_with("no-")) +return {AttrFeatureKind::NoFeature, AttrFeature.drop_front(3)}; + return {AttrFeatureKind::Feature, AttrFeature}; Ami-zhang wrote: Appreciate the review suggestion. The validation will be handled in isValidFeatureName(), with corresponding test cases added.Thanks! https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -85,6 +85,7 @@ struct ArchInfo { }; bool isValidArchName(StringRef Arch); +bool isValidFeatureName(StringRef Arch); Ami-zhang wrote: Done. https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -3195,6 +3195,17 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) { } } + if (Context.getTargetInfo().getTriple().isLoongArch()) { +for (const auto &Feature : ParsedAttrs.Features) { + StringRef CurFeature = Feature; + if (CurFeature.starts_with("!arch=")) { wangleiat wrote: According to `LoongArchTargetInfo::parseTargetAttr()`, this condition may always be false. https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -388,6 +388,76 @@ bool LoongArchTargetInfo::handleTargetFeatures( return true; } +enum class AttrFeatureKind { Arch, Tune, NoFeature, Feature, Invalid }; + +static std::pair +getAttrFeatureTypeAndValue(llvm::StringRef AttrFeature) { + if (auto Split = AttrFeature.split("="); !Split.second.empty()) { +if (Split.first.trim() == "arch") + return {AttrFeatureKind::Arch, Split.second.trim()}; +if (Split.first.trim() == "tune") + return {AttrFeatureKind::Tune, Split.second.trim()}; + } + if (AttrFeature.starts_with("no-")) +return {AttrFeatureKind::NoFeature, AttrFeature.drop_front(3)}; + return {AttrFeatureKind::Feature, AttrFeature}; wangleiat wrote: The default return may cause us to miss the check for invalid strings. (like this: "+lasx", here will be two plus signs in the generated IR) . Perhaps we can perform the check inside `isValidFeature()`?" https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -85,6 +85,7 @@ struct ArchInfo { }; bool isValidArchName(StringRef Arch); +bool isValidFeatureName(StringRef Arch); wangleiat wrote: Arch -> Feature https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple loongarch64-linux-gnu -fsyntax-only -verify %s + +// expected-error@+1 {{function multiversioning is not supported on the current target}} +void __attribute__((target("default"))) bar(void){} Ami-zhang wrote: Done. https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -0,0 +1,92 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --version 5 +// RUN: %clang --target=loongarch64-linux-gnu %s -S -emit-llvm -o - \ +// RUN: | FileCheck %s + +__attribute__((target("div32"))) +// CHECK-LABEL: define dso_local void @testdiv32( +// CHECK-SAME: ) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT:ret void +// +void testdiv32() {} + +__attribute__((target("arch=loongarch64"))) +// CHECK-LABEL: define dso_local void @testLoongarch64( +// CHECK-SAME: ) #[[ATTR1:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT:ret void +// +void testLoongarch64() {} + +__attribute__((target("arch=la64v1.0"))) +// CHECK-LABEL: define dso_local void @testLa64v10( +// CHECK-SAME: ) #[[ATTR1]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT:ret void +// +void testLa64v10() {} + +__attribute__((target("arch=la64v1.1"))) +// CHECK-LABEL: define dso_local void @testLa64v11( +// CHECK-SAME: ) #[[ATTR2:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT:ret void +// +void testLa64v11() {} + +__attribute__((target("arch=la464"))) +// CHECK-LABEL: define dso_local void @testLa464( +// CHECK-SAME: ) #[[ATTR3:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT:ret void +// +void testLa464() {} + +__attribute__((target("arch=la664"))) +// CHECK-LABEL: define dso_local void @testLa664( +// CHECK-SAME: ) #[[ATTR4:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT:ret void +// +void testLa664() {} + +__attribute__((target("arch=la664, no-div32"))) +// CHECK-LABEL: define dso_local void @la664Nodiv32( +// CHECK-SAME: ) #[[ATTR5:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT:ret void +// +void la664Nodiv32() {} + +__attribute__((target("tune=la464"))) +// CHECK-LABEL: define dso_local void @tuneLa664( +// CHECK-SAME: ) #[[ATTR6:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT:ret void +// +void tuneLa664() {} Ami-zhang wrote: Done. https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple loongarch64-linux-gnu -fsyntax-only -verify %s + +// expected-error@+1 {{function multiversioning is not supported on the current target}} +void __attribute__((target("default"))) bar(void){} + +// expected-error@+1 {{target(arch=..) attribute is not supported on targets missing invalid; specify an appropriate -march= or -mcpu=}} +void __attribute__((target("arch=invalid"))) foo(void){} + +//expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}} +int __attribute__((target("aaa"))) test_feature(void) { return 4; } + +//expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}} Ami-zhang wrote: Done. https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple loongarch64-linux-gnu -fsyntax-only -verify %s + +// expected-error@+1 {{function multiversioning is not supported on the current target}} +void __attribute__((target("default"))) bar(void){} + +// expected-error@+1 {{target(arch=..) attribute is not supported on targets missing invalid; specify an appropriate -march= or -mcpu=}} +void __attribute__((target("arch=invalid"))) foo(void){} + +//expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}} Ami-zhang wrote: Done. https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -388,6 +388,76 @@ bool LoongArchTargetInfo::handleTargetFeatures( return true; } +enum class AttrFeatureKind { Arch, Tune, NoFeature, Feature, Invalid }; + +static std::pair +getAttrFeatureTypeAndValue(llvm::StringRef AttrFeature) { + if (auto Split = AttrFeature.split("="); !Split.second.empty()) { +if (Split.first.trim() == "arch") + return {AttrFeatureKind::Arch, Split.second.trim()}; +if (Split.first.trim() == "tune") + return {AttrFeatureKind::Tune, Split.second.trim()}; + } + if (AttrFeature.starts_with("no-")) +return {AttrFeatureKind::NoFeature, AttrFeature.drop_front(3).trim()}; + return {AttrFeatureKind::Feature, AttrFeature.trim()}; Ami-zhang wrote: Done, thanks. https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
https://github.com/Ami-zhang updated https://github.com/llvm/llvm-project/pull/140700 >From 3355685f4debcd901f27efccc346de0f302a796c Mon Sep 17 00:00:00 2001 From: Ami-zhang Date: Wed, 14 May 2025 15:21:54 +0800 Subject: [PATCH 1/2] [Clang][LoongArch] Support target attribute for function This adds support under LoongArch for the target("..") attributes. The supported formats are: - "arch=" strings, that specify the architecture features for a function as per the -march=arch option. - "tune=" strings, that specify the tune-cpu cpu for a function as per -mtune. - "", "no-" enabled/disables the specific feature. --- clang/lib/Basic/Targets/LoongArch.cpp | 49 ++ clang/lib/Basic/Targets/LoongArch.h | 4 + clang/lib/Sema/SemaDeclAttr.cpp | 11 +++ clang/test/CodeGen/LoongArch/targetattr.c | 92 +++ clang/test/Sema/attr-target-loongarch.c | 19 .../llvm/TargetParser/LoongArchTargetParser.h | 1 + .../TargetParser/LoongArchTargetParser.cpp| 11 +++ 7 files changed, 187 insertions(+) create mode 100644 clang/test/CodeGen/LoongArch/targetattr.c create mode 100644 clang/test/Sema/attr-target-loongarch.c diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp index ca742797d7a3b..aee273a76a608 100644 --- a/clang/lib/Basic/Targets/LoongArch.cpp +++ b/clang/lib/Basic/Targets/LoongArch.cpp @@ -388,6 +388,51 @@ bool LoongArchTargetInfo::handleTargetFeatures( return true; } +ParsedTargetAttr +LoongArchTargetInfo::parseTargetAttr(StringRef Features) const { + ParsedTargetAttr Ret; + if (Features == "default") +return Ret; + SmallVector AttrFeatures; + Features.split(AttrFeatures, ","); + + for (auto &Feature : AttrFeatures) { +Feature = Feature.trim(); + +if (Feature.starts_with("arch=")) { + StringRef ArchValue = Feature.split("=").second.trim(); + + if (llvm::LoongArch::isValidArchName(ArchValue) || + ArchValue == "la64v1.0" || ArchValue == "la64v1.1") { +std::vector ArchFeatures; +if (llvm::LoongArch::getArchFeatures(ArchValue, ArchFeatures)) { + Ret.Features.insert(Ret.Features.end(), ArchFeatures.begin(), + ArchFeatures.end()); +} + +if (!Ret.CPU.empty()) + Ret.Duplicate = "arch="; +else if (ArchValue == "la64v1.0" || ArchValue == "la64v1.1") + Ret.CPU = "loongarch64"; +else + Ret.CPU = ArchValue; + } else { +Ret.Features.push_back("!arch=" + ArchValue.str()); + } +} else if (Feature.starts_with("tune=")) { + if (!Ret.Tune.empty()) +Ret.Duplicate = "tune="; + else +Ret.Tune = Feature.split("=").second.trim(); +} else if (Feature.starts_with("no-")) { + Ret.Features.push_back("-" + Feature.split("-").second.str()); +} else { + Ret.Features.push_back("+" + Feature.str()); +} + } + return Ret; +} + bool LoongArchTargetInfo::isValidCPUName(StringRef Name) const { return llvm::LoongArch::isValidCPUName(Name); } @@ -396,3 +441,7 @@ void LoongArchTargetInfo::fillValidCPUList( SmallVectorImpl &Values) const { llvm::LoongArch::fillValidCPUList(Values); } + +bool LoongArchTargetInfo::isValidFeatureName(StringRef Name) const { + return llvm::LoongArch::isValidFeatureName(Name); +} diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h index 4c7b53abfef9b..a83bb925bc310 100644 --- a/clang/lib/Basic/Targets/LoongArch.h +++ b/clang/lib/Basic/Targets/LoongArch.h @@ -101,6 +101,9 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { bool handleTargetFeatures(std::vector &Features, DiagnosticsEngine &Diags) override; + ParsedTargetAttr parseTargetAttr(StringRef Str) const override; + bool supportsTargetAttributeTune() const override { return true; } + bool initFeatureMap(llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, @@ -110,6 +113,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { bool isValidCPUName(StringRef Name) const override; void fillValidCPUList(SmallVectorImpl &Values) const override; + bool isValidFeatureName(StringRef Name) const override; }; class LLVM_LIBRARY_VISIBILITY LoongArch32TargetInfo diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 4d7f0455444f1..8e44e2e44bb24 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3195,6 +3195,17 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) { } } + if (Context.getTargetInfo().getTriple().isLoongArch()) { +for (const auto &Feature : ParsedAttrs.Features) { + StringRef CurFeature = Feature; + if (CurFeature.starts_with("!arch=")) { +StringRef ArchValue = CurFeature.split("=").second.trim(); +return Diag(Lite
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -0,0 +1,92 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --version 5 +// RUN: %clang --target=loongarch64-linux-gnu %s -S -emit-llvm -o - \ +// RUN: | FileCheck %s + +__attribute__((target("div32"))) +// CHECK-LABEL: define dso_local void @testdiv32( +// CHECK-SAME: ) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT:ret void +// +void testdiv32() {} + +__attribute__((target("arch=loongarch64"))) +// CHECK-LABEL: define dso_local void @testLoongarch64( +// CHECK-SAME: ) #[[ATTR1:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT:ret void +// +void testLoongarch64() {} + +__attribute__((target("arch=la64v1.0"))) +// CHECK-LABEL: define dso_local void @testLa64v10( +// CHECK-SAME: ) #[[ATTR1]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT:ret void +// +void testLa64v10() {} + +__attribute__((target("arch=la64v1.1"))) +// CHECK-LABEL: define dso_local void @testLa64v11( +// CHECK-SAME: ) #[[ATTR2:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT:ret void +// +void testLa64v11() {} + +__attribute__((target("arch=la464"))) +// CHECK-LABEL: define dso_local void @testLa464( +// CHECK-SAME: ) #[[ATTR3:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT:ret void +// +void testLa464() {} + +__attribute__((target("arch=la664"))) +// CHECK-LABEL: define dso_local void @testLa664( +// CHECK-SAME: ) #[[ATTR4:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT:ret void +// +void testLa664() {} + +__attribute__((target("arch=la664, no-div32"))) +// CHECK-LABEL: define dso_local void @la664Nodiv32( +// CHECK-SAME: ) #[[ATTR5:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT:ret void +// +void la664Nodiv32() {} + +__attribute__((target("tune=la464"))) +// CHECK-LABEL: define dso_local void @tuneLa664( +// CHECK-SAME: ) #[[ATTR6:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT:ret void +// +void tuneLa664() {} heiher wrote: Make the test function name align with the target feature. ```suggestion void tuneLa464() {} ``` https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
https://github.com/heiher approved this pull request. LGTM with nits. https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -388,6 +388,76 @@ bool LoongArchTargetInfo::handleTargetFeatures( return true; } +enum class AttrFeatureKind { Arch, Tune, NoFeature, Feature, Invalid }; + +static std::pair +getAttrFeatureTypeAndValue(llvm::StringRef AttrFeature) { + if (auto Split = AttrFeature.split("="); !Split.second.empty()) { +if (Split.first.trim() == "arch") + return {AttrFeatureKind::Arch, Split.second.trim()}; +if (Split.first.trim() == "tune") + return {AttrFeatureKind::Tune, Split.second.trim()}; + } + if (AttrFeature.starts_with("no-")) +return {AttrFeatureKind::NoFeature, AttrFeature.drop_front(3).trim()}; + return {AttrFeatureKind::Feature, AttrFeature.trim()}; heiher wrote: The caller has already performed `trim()`, so it's unnecessary here, just like `starts_with()` above doesn't use it either. ```suggestion return {AttrFeatureKind::Feature, AttrFeature}; ``` https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
https://github.com/heiher edited https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
https://github.com/Ami-zhang updated https://github.com/llvm/llvm-project/pull/140700 >From 3355685f4debcd901f27efccc346de0f302a796c Mon Sep 17 00:00:00 2001 From: Ami-zhang Date: Wed, 14 May 2025 15:21:54 +0800 Subject: [PATCH 1/2] [Clang][LoongArch] Support target attribute for function This adds support under LoongArch for the target("..") attributes. The supported formats are: - "arch=" strings, that specify the architecture features for a function as per the -march=arch option. - "tune=" strings, that specify the tune-cpu cpu for a function as per -mtune. - "", "no-" enabled/disables the specific feature. --- clang/lib/Basic/Targets/LoongArch.cpp | 49 ++ clang/lib/Basic/Targets/LoongArch.h | 4 + clang/lib/Sema/SemaDeclAttr.cpp | 11 +++ clang/test/CodeGen/LoongArch/targetattr.c | 92 +++ clang/test/Sema/attr-target-loongarch.c | 19 .../llvm/TargetParser/LoongArchTargetParser.h | 1 + .../TargetParser/LoongArchTargetParser.cpp| 11 +++ 7 files changed, 187 insertions(+) create mode 100644 clang/test/CodeGen/LoongArch/targetattr.c create mode 100644 clang/test/Sema/attr-target-loongarch.c diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp index ca742797d7a3b..aee273a76a608 100644 --- a/clang/lib/Basic/Targets/LoongArch.cpp +++ b/clang/lib/Basic/Targets/LoongArch.cpp @@ -388,6 +388,51 @@ bool LoongArchTargetInfo::handleTargetFeatures( return true; } +ParsedTargetAttr +LoongArchTargetInfo::parseTargetAttr(StringRef Features) const { + ParsedTargetAttr Ret; + if (Features == "default") +return Ret; + SmallVector AttrFeatures; + Features.split(AttrFeatures, ","); + + for (auto &Feature : AttrFeatures) { +Feature = Feature.trim(); + +if (Feature.starts_with("arch=")) { + StringRef ArchValue = Feature.split("=").second.trim(); + + if (llvm::LoongArch::isValidArchName(ArchValue) || + ArchValue == "la64v1.0" || ArchValue == "la64v1.1") { +std::vector ArchFeatures; +if (llvm::LoongArch::getArchFeatures(ArchValue, ArchFeatures)) { + Ret.Features.insert(Ret.Features.end(), ArchFeatures.begin(), + ArchFeatures.end()); +} + +if (!Ret.CPU.empty()) + Ret.Duplicate = "arch="; +else if (ArchValue == "la64v1.0" || ArchValue == "la64v1.1") + Ret.CPU = "loongarch64"; +else + Ret.CPU = ArchValue; + } else { +Ret.Features.push_back("!arch=" + ArchValue.str()); + } +} else if (Feature.starts_with("tune=")) { + if (!Ret.Tune.empty()) +Ret.Duplicate = "tune="; + else +Ret.Tune = Feature.split("=").second.trim(); +} else if (Feature.starts_with("no-")) { + Ret.Features.push_back("-" + Feature.split("-").second.str()); +} else { + Ret.Features.push_back("+" + Feature.str()); +} + } + return Ret; +} + bool LoongArchTargetInfo::isValidCPUName(StringRef Name) const { return llvm::LoongArch::isValidCPUName(Name); } @@ -396,3 +441,7 @@ void LoongArchTargetInfo::fillValidCPUList( SmallVectorImpl &Values) const { llvm::LoongArch::fillValidCPUList(Values); } + +bool LoongArchTargetInfo::isValidFeatureName(StringRef Name) const { + return llvm::LoongArch::isValidFeatureName(Name); +} diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h index 4c7b53abfef9b..a83bb925bc310 100644 --- a/clang/lib/Basic/Targets/LoongArch.h +++ b/clang/lib/Basic/Targets/LoongArch.h @@ -101,6 +101,9 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { bool handleTargetFeatures(std::vector &Features, DiagnosticsEngine &Diags) override; + ParsedTargetAttr parseTargetAttr(StringRef Str) const override; + bool supportsTargetAttributeTune() const override { return true; } + bool initFeatureMap(llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, @@ -110,6 +113,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { bool isValidCPUName(StringRef Name) const override; void fillValidCPUList(SmallVectorImpl &Values) const override; + bool isValidFeatureName(StringRef Name) const override; }; class LLVM_LIBRARY_VISIBILITY LoongArch32TargetInfo diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 4d7f0455444f1..8e44e2e44bb24 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3195,6 +3195,17 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) { } } + if (Context.getTargetInfo().getTriple().isLoongArch()) { +for (const auto &Feature : ParsedAttrs.Features) { + StringRef CurFeature = Feature; + if (CurFeature.starts_with("!arch=")) { +StringRef ArchValue = CurFeature.split("=").second.trim(); +return Diag(Lite
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -388,6 +388,51 @@ bool LoongArchTargetInfo::handleTargetFeatures( return true; } +ParsedTargetAttr +LoongArchTargetInfo::parseTargetAttr(StringRef Features) const { + ParsedTargetAttr Ret; + if (Features == "default") +return Ret; + SmallVector AttrFeatures; + Features.split(AttrFeatures, ","); + + for (auto &Feature : AttrFeatures) { +Feature = Feature.trim(); + +if (Feature.starts_with("arch=")) { tangaac wrote: I believe that the previous approach was essentially off-the-cuff, done whichever way was most convenient. If someone were to implement the same functionality for other architectures as well, they would find three pieces of code with very poor style. To leave behind code that is more ergonomic for future developers, at the very least, the logic for handling features should be separated and handled individually. ```c++ auto handleArch = [&](StringRef Feature) { ... } auto handleTune = [&](StringRef Feature) { ... } if(feature.startwith("arch=") handleArch(feature) else (feature.startwith("tune=") handleTune(feature) else if ( ... ) ... else { } ``` https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple loongarch64-linux-gnu -fsyntax-only -verify %s + +// expected-error@+1 {{function multiversioning is not supported on the current target}} +void __attribute__((target("default"))) bar(void){} + +// expected-error@+1 {{target(arch=..) attribute is not supported on targets missing invalid; specify an appropriate -march= or -mcpu=}} +void __attribute__((target("arch=invalid"))) foo(void){} + +//expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}} +int __attribute__((target("aaa"))) test_feature(void) { return 4; } + +//expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}} SixWeining wrote: ```suggestion // expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}} ``` https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple loongarch64-linux-gnu -fsyntax-only -verify %s + +// expected-error@+1 {{function multiversioning is not supported on the current target}} +void __attribute__((target("default"))) bar(void){} SixWeining wrote: ```suggestion void __attribute__((target("default"))) bar(void) {} ``` https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple loongarch64-linux-gnu -fsyntax-only -verify %s + +// expected-error@+1 {{function multiversioning is not supported on the current target}} +void __attribute__((target("default"))) bar(void){} + +// expected-error@+1 {{target(arch=..) attribute is not supported on targets missing invalid; specify an appropriate -march= or -mcpu=}} +void __attribute__((target("arch=invalid"))) foo(void){} + +//expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}} SixWeining wrote: ```suggestion // expected-warning@+1 {{unsupported 'aaa' in the 'target' attribute string; 'target' attribute ignored}} ``` https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
@@ -388,6 +388,51 @@ bool LoongArchTargetInfo::handleTargetFeatures( return true; } +ParsedTargetAttr +LoongArchTargetInfo::parseTargetAttr(StringRef Features) const { + ParsedTargetAttr Ret; + if (Features == "default") +return Ret; + SmallVector AttrFeatures; + Features.split(AttrFeatures, ","); + + for (auto &Feature : AttrFeatures) { +Feature = Feature.trim(); + +if (Feature.starts_with("arch=")) { tangaac wrote: It's recommended to use use a helper function to handle the types of features. Like below. If it's ok to define a FeatureKind enum, that would be even better. ~~~c++ static std::pair getFeatureTypeAndValue(llvm::StringRef Feature) { auto Split = Feature.split("="); if (!Split.second.empty()) return {Split.first.trim(), Split.second.trim()}; if (Feature.starts_with("no-")) return {"no", Feature.drop_front(3).trim()}; return {"feature", Feature.trim()}; } ~~~ ~~~c++ for (auto &Feature : AttrFeatures) { Feature = Feature.trim(); auto [Kind, Value] = getFeatureTypeAndValue(Feature); if (Kind == "arch") { } else if (Kind == "tune") { } .. } ~~~ https://github.com/llvm/llvm-project/pull/140700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
llvmbot wrote: @llvm/pr-subscribers-clang Author: None (Ami-zhang) Changes This adds support under LoongArch for the target("..") attributes. The supported formats are: - "arch=" strings, that specify the architecture features for a function as per the -march=arch option. - "tune= " strings, that specify the tune-cpu cpu for a function as per -mtune. - " ", "no- " enabled/disables the specific feature. --- Full diff: https://github.com/llvm/llvm-project/pull/140700.diff 7 Files Affected: - (modified) clang/lib/Basic/Targets/LoongArch.cpp (+49) - (modified) clang/lib/Basic/Targets/LoongArch.h (+4) - (modified) clang/lib/Sema/SemaDeclAttr.cpp (+11) - (added) clang/test/CodeGen/LoongArch/targetattr.c (+92) - (added) clang/test/Sema/attr-target-loongarch.c (+19) - (modified) llvm/include/llvm/TargetParser/LoongArchTargetParser.h (+1) - (modified) llvm/lib/TargetParser/LoongArchTargetParser.cpp (+11) ``diff diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp index ca742797d7a3b..aee273a76a608 100644 --- a/clang/lib/Basic/Targets/LoongArch.cpp +++ b/clang/lib/Basic/Targets/LoongArch.cpp @@ -388,6 +388,51 @@ bool LoongArchTargetInfo::handleTargetFeatures( return true; } +ParsedTargetAttr +LoongArchTargetInfo::parseTargetAttr(StringRef Features) const { + ParsedTargetAttr Ret; + if (Features == "default") +return Ret; + SmallVector AttrFeatures; + Features.split(AttrFeatures, ","); + + for (auto &Feature : AttrFeatures) { +Feature = Feature.trim(); + +if (Feature.starts_with("arch=")) { + StringRef ArchValue = Feature.split("=").second.trim(); + + if (llvm::LoongArch::isValidArchName(ArchValue) || + ArchValue == "la64v1.0" || ArchValue == "la64v1.1") { +std::vector ArchFeatures; +if (llvm::LoongArch::getArchFeatures(ArchValue, ArchFeatures)) { + Ret.Features.insert(Ret.Features.end(), ArchFeatures.begin(), + ArchFeatures.end()); +} + +if (!Ret.CPU.empty()) + Ret.Duplicate = "arch="; +else if (ArchValue == "la64v1.0" || ArchValue == "la64v1.1") + Ret.CPU = "loongarch64"; +else + Ret.CPU = ArchValue; + } else { +Ret.Features.push_back("!arch=" + ArchValue.str()); + } +} else if (Feature.starts_with("tune=")) { + if (!Ret.Tune.empty()) +Ret.Duplicate = "tune="; + else +Ret.Tune = Feature.split("=").second.trim(); +} else if (Feature.starts_with("no-")) { + Ret.Features.push_back("-" + Feature.split("-").second.str()); +} else { + Ret.Features.push_back("+" + Feature.str()); +} + } + return Ret; +} + bool LoongArchTargetInfo::isValidCPUName(StringRef Name) const { return llvm::LoongArch::isValidCPUName(Name); } @@ -396,3 +441,7 @@ void LoongArchTargetInfo::fillValidCPUList( SmallVectorImpl &Values) const { llvm::LoongArch::fillValidCPUList(Values); } + +bool LoongArchTargetInfo::isValidFeatureName(StringRef Name) const { + return llvm::LoongArch::isValidFeatureName(Name); +} diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h index 4c7b53abfef9b..a83bb925bc310 100644 --- a/clang/lib/Basic/Targets/LoongArch.h +++ b/clang/lib/Basic/Targets/LoongArch.h @@ -101,6 +101,9 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { bool handleTargetFeatures(std::vector &Features, DiagnosticsEngine &Diags) override; + ParsedTargetAttr parseTargetAttr(StringRef Str) const override; + bool supportsTargetAttributeTune() const override { return true; } + bool initFeatureMap(llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, @@ -110,6 +113,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { bool isValidCPUName(StringRef Name) const override; void fillValidCPUList(SmallVectorImpl &Values) const override; + bool isValidFeatureName(StringRef Name) const override; }; class LLVM_LIBRARY_VISIBILITY LoongArch32TargetInfo diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 4d7f0455444f1..8e44e2e44bb24 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3195,6 +3195,17 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) { } } + if (Context.getTargetInfo().getTriple().isLoongArch()) { +for (const auto &Feature : ParsedAttrs.Features) { + StringRef CurFeature = Feature; + if (CurFeature.starts_with("!arch=")) { +StringRef ArchValue = CurFeature.split("=").second.trim(); +return Diag(LiteralLoc, diag::err_attribute_unsupported) + << "target(arch=..)" << ArchValue; + } +} + } + if (ParsedAttrs.Duplicate != "") return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)
https://github.com/Ami-zhang created https://github.com/llvm/llvm-project/pull/140700 This adds support under LoongArch for the target("..") attributes. The supported formats are: - "arch=" strings, that specify the architecture features for a function as per the -march=arch option. - "tune=" strings, that specify the tune-cpu cpu for a function as per -mtune. - "", "no-" enabled/disables the specific feature. >From c5e14f95357d9d97255f50dab346232817df8e28 Mon Sep 17 00:00:00 2001 From: Ami-zhang Date: Wed, 14 May 2025 15:21:54 +0800 Subject: [PATCH] [Clang][LoongArch] Support target attribute for function This adds support under LoongArch for the target("..") attributes. The supported formats are: - "arch=" strings, that specify the architecture features for a function as per the -march=arch option. - "tune=" strings, that specify the tune-cpu cpu for a function as per -mtune. - "", "no-" enabled/disables the specific feature. --- clang/lib/Basic/Targets/LoongArch.cpp | 49 ++ clang/lib/Basic/Targets/LoongArch.h | 4 + clang/lib/Sema/SemaDeclAttr.cpp | 11 +++ clang/test/CodeGen/LoongArch/targetattr.c | 92 +++ clang/test/Sema/attr-target-loongarch.c | 19 .../llvm/TargetParser/LoongArchTargetParser.h | 1 + .../TargetParser/LoongArchTargetParser.cpp| 11 +++ 7 files changed, 187 insertions(+) create mode 100644 clang/test/CodeGen/LoongArch/targetattr.c create mode 100644 clang/test/Sema/attr-target-loongarch.c diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp index ca742797d7a3b..aee273a76a608 100644 --- a/clang/lib/Basic/Targets/LoongArch.cpp +++ b/clang/lib/Basic/Targets/LoongArch.cpp @@ -388,6 +388,51 @@ bool LoongArchTargetInfo::handleTargetFeatures( return true; } +ParsedTargetAttr +LoongArchTargetInfo::parseTargetAttr(StringRef Features) const { + ParsedTargetAttr Ret; + if (Features == "default") +return Ret; + SmallVector AttrFeatures; + Features.split(AttrFeatures, ","); + + for (auto &Feature : AttrFeatures) { +Feature = Feature.trim(); + +if (Feature.starts_with("arch=")) { + StringRef ArchValue = Feature.split("=").second.trim(); + + if (llvm::LoongArch::isValidArchName(ArchValue) || + ArchValue == "la64v1.0" || ArchValue == "la64v1.1") { +std::vector ArchFeatures; +if (llvm::LoongArch::getArchFeatures(ArchValue, ArchFeatures)) { + Ret.Features.insert(Ret.Features.end(), ArchFeatures.begin(), + ArchFeatures.end()); +} + +if (!Ret.CPU.empty()) + Ret.Duplicate = "arch="; +else if (ArchValue == "la64v1.0" || ArchValue == "la64v1.1") + Ret.CPU = "loongarch64"; +else + Ret.CPU = ArchValue; + } else { +Ret.Features.push_back("!arch=" + ArchValue.str()); + } +} else if (Feature.starts_with("tune=")) { + if (!Ret.Tune.empty()) +Ret.Duplicate = "tune="; + else +Ret.Tune = Feature.split("=").second.trim(); +} else if (Feature.starts_with("no-")) { + Ret.Features.push_back("-" + Feature.split("-").second.str()); +} else { + Ret.Features.push_back("+" + Feature.str()); +} + } + return Ret; +} + bool LoongArchTargetInfo::isValidCPUName(StringRef Name) const { return llvm::LoongArch::isValidCPUName(Name); } @@ -396,3 +441,7 @@ void LoongArchTargetInfo::fillValidCPUList( SmallVectorImpl &Values) const { llvm::LoongArch::fillValidCPUList(Values); } + +bool LoongArchTargetInfo::isValidFeatureName(StringRef Name) const { + return llvm::LoongArch::isValidFeatureName(Name); +} diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h index 4c7b53abfef9b..a83bb925bc310 100644 --- a/clang/lib/Basic/Targets/LoongArch.h +++ b/clang/lib/Basic/Targets/LoongArch.h @@ -101,6 +101,9 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { bool handleTargetFeatures(std::vector &Features, DiagnosticsEngine &Diags) override; + ParsedTargetAttr parseTargetAttr(StringRef Str) const override; + bool supportsTargetAttributeTune() const override { return true; } + bool initFeatureMap(llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, @@ -110,6 +113,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { bool isValidCPUName(StringRef Name) const override; void fillValidCPUList(SmallVectorImpl &Values) const override; + bool isValidFeatureName(StringRef Name) const override; }; class LLVM_LIBRARY_VISIBILITY LoongArch32TargetInfo diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 4d7f0455444f1..8e44e2e44bb24 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3195,6 +3195,17 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, St