[clang] [Clang][ARM] support arm target attribute, and warning for bad typo (PR #74812)

via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 14 01:08:44 PST 2023


https://github.com/hstk30-hw updated https://github.com/llvm/llvm-project/pull/74812

>From f9c6d46e73b612c261db5fdfebf49bb28003cf0d Mon Sep 17 00:00:00 2001
From: hstk30-hw <hanwei62 at huawei.com>
Date: Fri, 8 Dec 2023 14:29:33 +0800
Subject: [PATCH] feat: support arm target attribute, and warning for bad typo

---
 clang/lib/Basic/Targets/AArch64.cpp           |  6 +-
 clang/lib/Basic/Targets/ARM.cpp               | 87 +++++++++++++++++++
 clang/lib/Basic/Targets/ARM.h                 |  2 +
 clang/lib/Sema/SemaDeclAttr.cpp               |  3 +
 clang/test/CodeGen/arm-targetattr.c           | 13 +++
 .../arm-ignore-branch-protection-option.c     |  4 +-
 .../Sema/arm-branch-protection-attr-warn.c    | 10 +--
 clang/test/Sema/arm-branch-protection.c       | 32 +++----
 clang/test/Sema/attr-target.c                 |  8 ++
 9 files changed, 141 insertions(+), 24 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-targetattr.c

diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index def16c032c869e..66f0c0e159c2ae 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -1085,13 +1085,17 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
       FoundArch = true;
       std::pair<StringRef, StringRef> Split =
           Feature.split("=").second.trim().split("+");
+      if (Split.first == "")
+        continue;
       const std::optional<llvm::AArch64::ArchInfo> AI =
           llvm::AArch64::parseArch(Split.first);
 
       // Parse the architecture version, adding the required features to
       // Ret.Features.
-      if (!AI)
+      if (!AI) {
+        Ret.Features.push_back("+UNKNOWN");
         continue;
+      }
       Ret.Features.push_back(AI->ArchFeature.str());
       // Add any extra features, after the +
       SplitAndAddFeatures(Split.second, Ret.Features);
diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp
index ce7e4d4639ceac..7ed64f4f44a9b5 100644
--- a/clang/lib/Basic/Targets/ARM.cpp
+++ b/clang/lib/Basic/Targets/ARM.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "ARM.h"
+#include "clang/AST/Attr.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/TargetBuiltins.h"
@@ -639,6 +640,92 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
   return true;
 }
 
+// Parse ARM Target attributes, which are a comma separated list of:
+//  "arch=<arch>" - parsed to features as per -march=..
+//  "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>
+//  "tune=<cpu>" - TuneCPU set to <cpu>
+//  "feature", "no-feature" - Add (or remove) feature.
+//  "+feature", "+nofeature" - Add (or remove) feature.
+ParsedTargetAttr ARMTargetInfo::parseTargetAttr(StringRef Features) const {
+  ParsedTargetAttr Ret;
+  if (Features == "default")
+    return Ret;
+  SmallVector<StringRef, 1> AttrFeatures;
+  Features.split(AttrFeatures, ",");
+  bool FoundArch = false;
+
+  auto SplitAndAddFeatures = [](StringRef FeatString,
+                                std::vector<std::string> &Features) {
+    SmallVector<StringRef, 8> SplitFeatures;
+    FeatString.split(SplitFeatures, StringRef("+"), -1, false);
+    for (StringRef Feature : SplitFeatures) {
+      StringRef FeatureName = llvm::ARM::getArchExtFeature(Feature);
+      if (!FeatureName.empty())
+        Features.push_back(FeatureName.str());
+      else
+        // Pushing the original feature string to give a sema error later on
+        // when they get checked.
+        Features.push_back(Feature.str());
+    }
+  };
+
+  for (auto &Feature : AttrFeatures) {
+    Feature = Feature.trim();
+    if (Feature.startswith("fpmath="))
+      continue;
+
+    if (Feature.startswith("branch-protection=")) {
+      Ret.BranchProtection = Feature.split('=').second.trim();
+      continue;
+    }
+
+    if (Feature.startswith("arch=")) {
+      if (FoundArch)
+        Ret.Duplicate = "arch=";
+      FoundArch = true;
+      std::pair<StringRef, StringRef> Split =
+          Feature.split("=").second.trim().split("+");
+      if (Split.first == "")
+        continue;
+      llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(Split.first);
+
+      // Parse the architecture version, adding the required features to
+      // Ret.Features.
+      std::vector<StringRef> FeatureStrs;
+      if (ArchKind == llvm::ARM::ArchKind::INVALID) {
+        Ret.Features.push_back("+UNKNOWN");
+        continue;
+      }
+      std::string ArchFeature = ("+" + llvm::ARM::getArchName(ArchKind)).str();
+      Ret.Features.push_back(ArchFeature);
+      // Add any extra features, after the +
+      SplitAndAddFeatures(Split.second, Ret.Features);
+    } else if (Feature.startswith("cpu=")) {
+      if (!Ret.CPU.empty())
+        Ret.Duplicate = "cpu=";
+      else {
+        // Split the cpu string into "cpu=", "cortex-a710" and any remaining
+        // "+feat" features.
+        std::pair<StringRef, StringRef> Split =
+            Feature.split("=").second.trim().split("+");
+        Ret.CPU = Split.first;
+        SplitAndAddFeatures(Split.second, Ret.Features);
+      }
+    } else if (Feature.startswith("tune=")) {
+      if (!Ret.Tune.empty())
+        Ret.Duplicate = "tune=";
+      else
+        Ret.Tune = Feature.split("=").second.trim();
+    } else if (Feature.startswith("no-"))
+      Ret.Features.push_back("-" + Feature.split("-").second.str());
+    else if (Feature.startswith("+")) {
+      SplitAndAddFeatures(Feature, Ret.Features);
+    } else
+      Ret.Features.push_back("+" + Feature.str());
+  }
+  return Ret;
+}
+
 bool ARMTargetInfo::hasFeature(StringRef Feature) const {
   return llvm::StringSwitch<bool>(Feature)
       .Case("arm", true)
diff --git a/clang/lib/Basic/Targets/ARM.h b/clang/lib/Basic/Targets/ARM.h
index b1aa2794c7e4c3..a14d10c52220ba 100644
--- a/clang/lib/Basic/Targets/ARM.h
+++ b/clang/lib/Basic/Targets/ARM.h
@@ -134,6 +134,8 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo {
   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
                  StringRef CPU,
                  const std::vector<std::string> &FeaturesVec) const override;
+  ParsedTargetAttr parseTargetAttr(StringRef Str) const override;
+  bool supportsTargetAttributeTune() const override { return false; }
 
   bool isValidFeatureName(StringRef Feature) const override {
     // We pass soft-float-abi in as a -target-feature, but the backend figures
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 5b29b05dee54b3..5daf1b98dc8454 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3462,6 +3462,9 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
 
   for (const auto &Feature : ParsedAttrs.Features) {
     auto CurFeature = StringRef(Feature).drop_front(); // remove + or -.
+    if (CurFeature == "UNKNOWN")
+      return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
+             << Unknown << None << AttrStr << Target;
     if (!Context.getTargetInfo().isValidFeatureName(CurFeature))
       return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
              << Unsupported << None << CurFeature << Target;
diff --git a/clang/test/CodeGen/arm-targetattr.c b/clang/test/CodeGen/arm-targetattr.c
new file mode 100644
index 00000000000000..fd35a2da24bc3c
--- /dev/null
+++ b/clang/test/CodeGen/arm-targetattr.c
@@ -0,0 +1,13 @@
+// REQUIRES: arm-registered-target
+// RUN: %clang -target arm-none-eabi -emit-llvm -S -o - %s | FileCheck %s
+
+// CHECK-LABEL: @v8() #0
+__attribute__((target("arch=armv8-a")))
+void v8() {}
+// CHECK-LABEL: @v8crc() #1
+__attribute__((target("arch=armv8-a+crc")))
+void v8crc() {}
+
+// CHECK: attributes #0 = { {{.*}} "target-features"="{{.*}}+armv8-a{{.*}}" }
+// CHECK: attributes #1 = { {{.*}} "target-features"="{{.*}}+armv8-a,+crc{{.*}}" }
+
diff --git a/clang/test/Frontend/arm-ignore-branch-protection-option.c b/clang/test/Frontend/arm-ignore-branch-protection-option.c
index 99a2accef3ae2f..80b21d774d7ad6 100644
--- a/clang/test/Frontend/arm-ignore-branch-protection-option.c
+++ b/clang/test/Frontend/arm-ignore-branch-protection-option.c
@@ -3,10 +3,10 @@
 /// Check warning for
 // RUN: %clang -target arm-arm-none-eabi -march=armv7-m -mbranch-protection=bti %s -S -emit-llvm -o - 2>&1 | FileCheck %s
 
-__attribute__((target("arch=cortex-m0"))) void f() {}
+__attribute__((target("cpu=cortex-m0"))) void f() {}
 
 // CHECK: warning: ignoring the 'branch-protection' attribute because the 'cortex-m0' architecture does not support it [-Wbranch-protection]
-// CHECK-NEXT: __attribute__((target("arch=cortex-m0"))) void f() {}
+// CHECK-NEXT: __attribute__((target("cpu=cortex-m0"))) void f() {}
 
 /// Check there are no branch protection function attributes
 
diff --git a/clang/test/Sema/arm-branch-protection-attr-warn.c b/clang/test/Sema/arm-branch-protection-attr-warn.c
index 864bff9b9e8a45..0c7d3a3df56553 100644
--- a/clang/test/Sema/arm-branch-protection-attr-warn.c
+++ b/clang/test/Sema/arm-branch-protection-attr-warn.c
@@ -1,16 +1,16 @@
 // RUN: %clang_cc1 -triple thumbv6m -verify -fsyntax-only %s
 
 // expected-warning at +1 {{unsupported 'branch-protection' in the 'target' attribute string; 'target' attribute ignored}}
-__attribute__((target("arch=cortex-m0,branch-protection=bti"))) void f1(void) {}
+__attribute__((target("cpu=cortex-m0,branch-protection=bti"))) void f1(void) {}
 
 // expected-warning at +1 {{unsupported 'branch-protection' in the 'target' attribute string; 'target' attribute ignored}}
-__attribute__((target("arch=cortex-m0,branch-protection=pac-ret"))) void f2(void) {}
+__attribute__((target("cpu=cortex-m0,branch-protection=pac-ret"))) void f2(void) {}
 
 // expected-warning at +1 {{unsupported 'branch-protection' in the 'target' attribute string; 'target' attribute ignored}}
-__attribute__((target("arch=cortex-m0,branch-protection=bti+pac-ret"))) void f3(void) {}
+__attribute__((target("cpu=cortex-m0,branch-protection=bti+pac-ret"))) void f3(void) {}
 
 // expected-warning at +1 {{unsupported 'branch-protection' in the 'target' attribute string; 'target' attribute ignored}}
-__attribute__((target("arch=cortex-m0,branch-protection=bti+pac-ret+leaf"))) void f4(void) {}
+__attribute__((target("cpu=cortex-m0,branch-protection=bti+pac-ret+leaf"))) void f4(void) {}
 
 // expected-warning at +1 {{unsupported 'branch-protection' in the 'target' attribute string; 'target' attribute ignored}}
-__attribute__((target("arch=cortex-a17,thumb,branch-protection=bti+pac-ret+leaf"))) void f5(void) {}
+__attribute__((target("cpu=cortex-a17,thumb,branch-protection=bti+pac-ret+leaf"))) void f5(void) {}
diff --git a/clang/test/Sema/arm-branch-protection.c b/clang/test/Sema/arm-branch-protection.c
index 2769164af0edcb..653d0a07b3b95a 100644
--- a/clang/test/Sema/arm-branch-protection.c
+++ b/clang/test/Sema/arm-branch-protection.c
@@ -2,22 +2,22 @@
 
 // expected-no-diagnostics
 // Armv8.1-M.Main
-__attribute__((target("arch=cortex-m55,branch-protection=bti"))) void f1(void) {}
-__attribute__((target("arch=cortex-m55,branch-protection=pac-ret"))) void f2(void) {}
-__attribute__((target("arch=cortex-m55,branch-protection=bti+pac-ret"))) void f3(void) {}
-__attribute__((target("arch=cortex-m55,branch-protection=bti+pac-ret+leaf"))) void f4(void) {}
+__attribute__((target("cpu=cortex-m55,branch-protection=bti"))) void f1(void) {}
+__attribute__((target("cpu=cortex-m55,branch-protection=pac-ret"))) void f2(void) {}
+__attribute__((target("cpu=cortex-m55,branch-protection=bti+pac-ret"))) void f3(void) {}
+__attribute__((target("cpu=cortex-m55,branch-protection=bti+pac-ret+leaf"))) void f4(void) {}
 // Armv8-M.Main
-__attribute__((target("arch=cortex-m33,branch-protection=bti"))) void f5(void) {}
-__attribute__((target("arch=cortex-m33,branch-protection=pac-ret"))) void f6(void) {}
-__attribute__((target("arch=cortex-m33,branch-protection=bti+pac-ret"))) void f7(void) {}
-__attribute__((target("arch=cortex-m33,branch-protection=bti+pac-ret+leaf"))) void f8(void) {}
+__attribute__((target("cpu=cortex-m33,branch-protection=bti"))) void f5(void) {}
+__attribute__((target("cpu=cortex-m33,branch-protection=pac-ret"))) void f6(void) {}
+__attribute__((target("cpu=cortex-m33,branch-protection=bti+pac-ret"))) void f7(void) {}
+__attribute__((target("cpu=cortex-m33,branch-protection=bti+pac-ret+leaf"))) void f8(void) {}
 // Armv7-M
-__attribute__((target("arch=cortex-m3,branch-protection=bti"))) void f9(void) {}
-__attribute__((target("arch=cortex-m3,branch-protection=pac-ret"))) void f10(void) {}
-__attribute__((target("arch=cortex-m3,branch-protection=bti+pac-ret"))) void f11(void) {}
-__attribute__((target("arch=cortex-m3,branch-protection=bti+pac-ret+leaf"))) void f12(void) {}
+__attribute__((target("cpu=cortex-m3,branch-protection=bti"))) void f9(void) {}
+__attribute__((target("cpu=cortex-m3,branch-protection=pac-ret"))) void f10(void) {}
+__attribute__((target("cpu=cortex-m3,branch-protection=bti+pac-ret"))) void f11(void) {}
+__attribute__((target("cpu=cortex-m3,branch-protection=bti+pac-ret+leaf"))) void f12(void) {}
 // Armv7E-M
-__attribute__((target("arch=cortex-m4,branch-protection=bti"))) void f13(void) {}
-__attribute__((target("arch=cortex-m4,branch-protection=pac-ret"))) void f14(void) {}
-__attribute__((target("arch=cortex-m4,branch-protection=bti+pac-ret"))) void f15(void) {}
-__attribute__((target("arch=cortex-m4,branch-protection=bti+pac-ret+leaf"))) void f16(void) {}
+__attribute__((target("cpu=cortex-m4,branch-protection=bti"))) void f13(void) {}
+__attribute__((target("cpu=cortex-m4,branch-protection=pac-ret"))) void f14(void) {}
+__attribute__((target("cpu=cortex-m4,branch-protection=bti+pac-ret"))) void f15(void) {}
+__attribute__((target("cpu=cortex-m4,branch-protection=bti+pac-ret+leaf"))) void f16(void) {}
diff --git a/clang/test/Sema/attr-target.c b/clang/test/Sema/attr-target.c
index 5328f056507a71..288ff87cc88a7c 100644
--- a/clang/test/Sema/attr-target.c
+++ b/clang/test/Sema/attr-target.c
@@ -63,6 +63,14 @@ int __attribute__((target("tune=cortex-a710,tune=neoverse-n2"))) pear_tree(void)
 // no warning - branch-protection should work on aarch64
 int __attribute__((target("branch-protection=none"))) birch_tree(void) { return 5; }
 
+//expected-warning at +1 {{unknown 'arch=armv8-a-typo' in the 'target' attribute string; 'target' attribute ignored}}
+void __attribute__((target("arch=armv8-a-typo"))) typo_arch1(void) {}
+
+#elifdef __arm__
+
+//expected-warning at +1 {{unknown 'arch=armv8-b-typo' in the 'target' attribute string; 'target' attribute ignored}}
+void __attribute__((target("arch=armv8-b-typo"))) typo_arch2(void) {}
+
 #elifdef __powerpc__
 
 int __attribute__((target("float128,arch=pwr9"))) foo(void) { return 4; }



More information about the cfe-commits mailing list