[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 7 22:45:19 PST 2023
https://github.com/hstk30-hw created https://github.com/llvm/llvm-project/pull/74812
This adds support under ARM for the target("..") attributes like AArch64 https://reviews.llvm.org/D133848 . And warning for bad typo for "arch=".
>From 8a84eaf11bb76aba7db5243390f246d40b3f9630 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 +++
.../Sema/arm-branch-protection-attr-warn.c | 10 +--
clang/test/Sema/arm-branch-protection.c | 32 +++----
clang/test/Sema/attr-target.c | 8 ++
8 files changed, 139 insertions(+), 22 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 c71af71eba60ce..934de9d0c7b68f 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -1065,13 +1065,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..3a7081c34ebc5c 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..81c7379a2e9791 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 cdb769a883550d..d74e735105c934 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3457,6 +3457,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/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