[clang] [llvm] [Clang][LoongArch] Support target attribute for function (PR #140700)

2025-05-29 Thread LLVM Continuous Integration via cfe-commits

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
/home/buildbot/buildbot-root/gcc-no-asserts/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
^
/home/buildbot/buildbot-root/gcc-no-asserts/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
^
/home/buildbot/buildbot-root/gcc-no-asserts/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
^
:17:42: note: previous match ended here
define dso_local void @testLa64v10() #1 {
 ^
:18:1: note: non-matching line after 
previous match is here
 ret void
^
/home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/clang/test/CodeGen/LoongArch/targetattr.c:32:16:
 error: CHECK-NEXT: is not on the line after the previous 
match
// CHECK-NEXT: [[ENTRY:.*:]]
   ^
:26:1: note: 'next' match was here
; Function Attrs: noinline nounwind optnone
^
...

```



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)

2025-05-29 Thread LLVM Continuous Integration via cfe-commits

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)

2025-05-29 Thread via cfe-commits

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)

2025-05-28 Thread via cfe-commits


@@ -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)

2025-05-28 Thread via cfe-commits

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)

2025-05-28 Thread via cfe-commits


@@ -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)

2025-05-28 Thread via cfe-commits

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)

2025-05-28 Thread via cfe-commits


@@ -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)

2025-05-28 Thread via cfe-commits

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)

2025-05-28 Thread via cfe-commits

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)

2025-05-28 Thread via cfe-commits


@@ -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)

2025-05-28 Thread via cfe-commits

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)

2025-05-28 Thread via cfe-commits

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)

2025-05-28 Thread via cfe-commits

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)

2025-05-28 Thread via cfe-commits


@@ -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)

2025-05-28 Thread via cfe-commits


@@ -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)

2025-05-28 Thread via cfe-commits


@@ -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)

2025-05-28 Thread via cfe-commits


@@ -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)

2025-05-28 Thread via cfe-commits


@@ -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)

2025-05-26 Thread via cfe-commits


@@ -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)

2025-05-26 Thread via cfe-commits


@@ -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)

2025-05-25 Thread via cfe-commits


@@ -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)

2025-05-25 Thread via cfe-commits


@@ -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)

2025-05-25 Thread via cfe-commits


@@ -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)

2025-05-25 Thread via cfe-commits

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)

2025-05-25 Thread via cfe-commits


@@ -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)

2025-05-25 Thread via cfe-commits

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)

2025-05-25 Thread via cfe-commits


@@ -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)

2025-05-25 Thread via cfe-commits

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)

2025-05-23 Thread via cfe-commits

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)

2025-05-21 Thread via cfe-commits


@@ -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)

2025-05-20 Thread Lu Weining via cfe-commits


@@ -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)

2025-05-20 Thread Lu Weining via cfe-commits


@@ -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)

2025-05-20 Thread Lu Weining via cfe-commits


@@ -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)

2025-05-20 Thread via cfe-commits


@@ -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)

2025-05-20 Thread via cfe-commits

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)

2025-05-20 Thread via cfe-commits

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