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 <hanwe...@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@+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@+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@+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@+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@+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@+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@+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; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits