Skip to content

[Clang][RISCV] Recognize unsupport target feature by supporting isValidFeatureName #106495

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Sep 9, 2024

Conversation

BeMg
Copy link
Contributor

@BeMg BeMg commented Aug 29, 2024

This patch makes unsupported target attributes emit a warning and ignore the target attribute during semantic checks. The changes include:

  1. Adding the RISCVTargetInfo::isValidFeatureName function.
  2. Rejecting non-full-arch strings in the handleFullArchString function.
  3. Adding test cases to demonstrate the warning behavior.

@llvmbot llvmbot added clang Clang issues not falling into any other category backend:RISC-V clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Aug 29, 2024
@llvmbot
Copy link
Member

llvmbot commented Aug 29, 2024

@llvm/pr-subscribers-backend-risc-v

Author: Piyou Chen (BeMg)

Changes

…isValidFeatureName

This patch makes unsupported target attributes emit a warning and ignore the target attribute during semantic checks. The changes include:

  1. Adding the RISCVTargetInfo::isValidFeatureName function.
  2. Adding a '+' sign to __RISCV_TargetAttrNeedOverride because checkTargetAttr will remove the sign.
  3. Rejecting non-full-arch strings in the handleFullArchString function.
  4. Adding test cases to demonstrate the warning behavior.

Full diff: https://github.com/llvm/llvm-project/pull/106495.diff

4 Files Affected:

  • (modified) clang/lib/Basic/Targets/RISCV.cpp (+16-2)
  • (modified) clang/lib/Basic/Targets/RISCV.h (+1)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (+11-4)
  • (modified) clang/test/Sema/attr-target-riscv.c (+9)
diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp
index 1f8a8cd1462c9d..1d6f49ca232692 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -257,7 +257,7 @@ bool RISCVTargetInfo::initFeatureMap(
 
   // If a target attribute specified a full arch string, override all the ISA
   // extension target features.
-  const auto I = llvm::find(FeaturesVec, "__RISCV_TargetAttrNeedOverride");
+  const auto I = llvm::find(FeaturesVec, "+__RISCV_TargetAttrNeedOverride");
   if (I != FeaturesVec.end()) {
     std::vector<std::string> OverrideFeatures(std::next(I), FeaturesVec.end());
 
@@ -391,7 +391,14 @@ void RISCVTargetInfo::fillValidTuneCPUList(
 
 static void handleFullArchString(StringRef FullArchStr,
                                  std::vector<std::string> &Features) {
-  Features.push_back("__RISCV_TargetAttrNeedOverride");
+
+  // Should be full arch string.
+  if (!FullArchStr.starts_with("rv")) {
+    Features.push_back(FullArchStr.str());
+    return;
+  }
+
+  Features.push_back("+__RISCV_TargetAttrNeedOverride");
   auto RII = llvm::RISCVISAInfo::parseArchString(
       FullArchStr, /* EnableExperimentalExtension */ true);
   if (llvm::errorToBool(RII.takeError())) {
@@ -485,3 +492,10 @@ bool RISCVTargetInfo::validateCpuSupports(StringRef Feature) const {
   // __riscv_feature_bits structure.
   return -1 != llvm::RISCVISAInfo::getRISCVFeaturesBitsInfo(Feature).second;
 }
+
+bool RISCVTargetInfo::isValidFeatureName(StringRef Name) const {
+  if (Name == "__RISCV_TargetAttrNeedOverride")
+    return true;
+
+  return llvm::RISCVISAInfo::isSupportedExtensionFeature(Name);
+}
diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index 626274b8fc437c..b808ccc8e9cfe9 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -130,6 +130,7 @@ class RISCVTargetInfo : public TargetInfo {
   bool supportsCpuSupports() const override { return getTriple().isOSLinux(); }
   bool supportsCpuInit() const override { return getTriple().isOSLinux(); }
   bool validateCpuSupports(StringRef Feature) const override;
+  bool isValidFeatureName(StringRef Name) const override;
 };
 class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
 public:
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 1e074298ac5289..81cff8d7362ad5 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2993,10 +2993,17 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
     return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
            << Unknown << Tune << ParsedAttrs.Tune << Target;
 
-  if (Context.getTargetInfo().getTriple().isRISCV() &&
-      ParsedAttrs.Duplicate != "")
-    return Diag(LiteralLoc, diag::err_duplicate_target_attribute)
-           << Duplicate << None << ParsedAttrs.Duplicate << Target;
+  if (Context.getTargetInfo().getTriple().isRISCV()) {
+    if (ParsedAttrs.Duplicate != "")
+      return Diag(LiteralLoc, diag::err_duplicate_target_attribute)
+             << Duplicate << None << ParsedAttrs.Duplicate << Target;
+    for (const auto &Feature : ParsedAttrs.Features) {
+      auto CurFeature = StringRef(Feature);
+      if (!CurFeature.starts_with("+") && !CurFeature.starts_with("-"))
+        return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
+               << Unsupported << None << AttrStr << Target;
+    }
+  }
 
   if (ParsedAttrs.Duplicate != "")
     return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
diff --git a/clang/test/Sema/attr-target-riscv.c b/clang/test/Sema/attr-target-riscv.c
index ed4e2915d6c6ef..01d928c1d78e48 100644
--- a/clang/test/Sema/attr-target-riscv.c
+++ b/clang/test/Sema/attr-target-riscv.c
@@ -4,3 +4,12 @@
 int __attribute__((target("arch=rv64g"))) foo(void) { return 0; }
 //expected-error@+1 {{redefinition of 'foo'}}
 int __attribute__((target("arch=rv64gc"))) foo(void) { return 0; }
+
+//expected-warning@+1 {{unsupported 'notafeature' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("arch=+notafeature"))) UnsupportFeature(void) { return 0; }
+
+//expected-warning@+1 {{unsupported 'arch=+zba,zbb' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("arch=+zba,zbb"))) WithoutAddSigned(void) { return 0; }
+
+//expected-warning@+1 {{unsupported 'arch=zba' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("arch=zba"))) WithoutAddSigned2(void) { return 0; }

@llvmbot
Copy link
Member

llvmbot commented Aug 29, 2024

@llvm/pr-subscribers-clang

Author: Piyou Chen (BeMg)

Changes

…isValidFeatureName

This patch makes unsupported target attributes emit a warning and ignore the target attribute during semantic checks. The changes include:

  1. Adding the RISCVTargetInfo::isValidFeatureName function.
  2. Adding a '+' sign to __RISCV_TargetAttrNeedOverride because checkTargetAttr will remove the sign.
  3. Rejecting non-full-arch strings in the handleFullArchString function.
  4. Adding test cases to demonstrate the warning behavior.

Full diff: https://github.com/llvm/llvm-project/pull/106495.diff

4 Files Affected:

  • (modified) clang/lib/Basic/Targets/RISCV.cpp (+16-2)
  • (modified) clang/lib/Basic/Targets/RISCV.h (+1)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (+11-4)
  • (modified) clang/test/Sema/attr-target-riscv.c (+9)
diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp
index 1f8a8cd1462c9d..1d6f49ca232692 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -257,7 +257,7 @@ bool RISCVTargetInfo::initFeatureMap(
 
   // If a target attribute specified a full arch string, override all the ISA
   // extension target features.
-  const auto I = llvm::find(FeaturesVec, "__RISCV_TargetAttrNeedOverride");
+  const auto I = llvm::find(FeaturesVec, "+__RISCV_TargetAttrNeedOverride");
   if (I != FeaturesVec.end()) {
     std::vector<std::string> OverrideFeatures(std::next(I), FeaturesVec.end());
 
@@ -391,7 +391,14 @@ void RISCVTargetInfo::fillValidTuneCPUList(
 
 static void handleFullArchString(StringRef FullArchStr,
                                  std::vector<std::string> &Features) {
-  Features.push_back("__RISCV_TargetAttrNeedOverride");
+
+  // Should be full arch string.
+  if (!FullArchStr.starts_with("rv")) {
+    Features.push_back(FullArchStr.str());
+    return;
+  }
+
+  Features.push_back("+__RISCV_TargetAttrNeedOverride");
   auto RII = llvm::RISCVISAInfo::parseArchString(
       FullArchStr, /* EnableExperimentalExtension */ true);
   if (llvm::errorToBool(RII.takeError())) {
@@ -485,3 +492,10 @@ bool RISCVTargetInfo::validateCpuSupports(StringRef Feature) const {
   // __riscv_feature_bits structure.
   return -1 != llvm::RISCVISAInfo::getRISCVFeaturesBitsInfo(Feature).second;
 }
+
+bool RISCVTargetInfo::isValidFeatureName(StringRef Name) const {
+  if (Name == "__RISCV_TargetAttrNeedOverride")
+    return true;
+
+  return llvm::RISCVISAInfo::isSupportedExtensionFeature(Name);
+}
diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index 626274b8fc437c..b808ccc8e9cfe9 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -130,6 +130,7 @@ class RISCVTargetInfo : public TargetInfo {
   bool supportsCpuSupports() const override { return getTriple().isOSLinux(); }
   bool supportsCpuInit() const override { return getTriple().isOSLinux(); }
   bool validateCpuSupports(StringRef Feature) const override;
+  bool isValidFeatureName(StringRef Name) const override;
 };
 class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
 public:
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 1e074298ac5289..81cff8d7362ad5 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2993,10 +2993,17 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
     return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
            << Unknown << Tune << ParsedAttrs.Tune << Target;
 
-  if (Context.getTargetInfo().getTriple().isRISCV() &&
-      ParsedAttrs.Duplicate != "")
-    return Diag(LiteralLoc, diag::err_duplicate_target_attribute)
-           << Duplicate << None << ParsedAttrs.Duplicate << Target;
+  if (Context.getTargetInfo().getTriple().isRISCV()) {
+    if (ParsedAttrs.Duplicate != "")
+      return Diag(LiteralLoc, diag::err_duplicate_target_attribute)
+             << Duplicate << None << ParsedAttrs.Duplicate << Target;
+    for (const auto &Feature : ParsedAttrs.Features) {
+      auto CurFeature = StringRef(Feature);
+      if (!CurFeature.starts_with("+") && !CurFeature.starts_with("-"))
+        return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
+               << Unsupported << None << AttrStr << Target;
+    }
+  }
 
   if (ParsedAttrs.Duplicate != "")
     return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
diff --git a/clang/test/Sema/attr-target-riscv.c b/clang/test/Sema/attr-target-riscv.c
index ed4e2915d6c6ef..01d928c1d78e48 100644
--- a/clang/test/Sema/attr-target-riscv.c
+++ b/clang/test/Sema/attr-target-riscv.c
@@ -4,3 +4,12 @@
 int __attribute__((target("arch=rv64g"))) foo(void) { return 0; }
 //expected-error@+1 {{redefinition of 'foo'}}
 int __attribute__((target("arch=rv64gc"))) foo(void) { return 0; }
+
+//expected-warning@+1 {{unsupported 'notafeature' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("arch=+notafeature"))) UnsupportFeature(void) { return 0; }
+
+//expected-warning@+1 {{unsupported 'arch=+zba,zbb' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("arch=+zba,zbb"))) WithoutAddSigned(void) { return 0; }
+
+//expected-warning@+1 {{unsupported 'arch=zba' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("arch=zba"))) WithoutAddSigned2(void) { return 0; }

@dtcxzyw dtcxzyw changed the title [Clang][RISCV] Recognize unsupport target feature by supporting... [Clang][RISCV] Recognize unsupport target feature by supporting isValidFeatureName Aug 29, 2024
@BeMg BeMg force-pushed the add-isValidFeatureName-for-RISCV branch from ef599d0 to 81d79a5 Compare August 31, 2024 12:10
@BeMg
Copy link
Contributor Author

BeMg commented Aug 31, 2024

Rebase with #106680 and drop the __RISCV_TargetAttrNeedOverride relate code section.

@BeMg BeMg requested review from topperc, kito-cheng and jrtc27 August 31, 2024 12:16
@BeMg
Copy link
Contributor Author

BeMg commented Sep 5, 2024

ping

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@BeMg BeMg merged commit 022b3c2 into llvm:main Sep 9, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:RISC-V clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants