[clang] 712de9d - [AArch64] Add all predecessor archs in target info
Daniel Kiss via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 27 01:23:32 PDT 2022
Author: Daniel Kiss
Date: 2022-09-27T10:23:21+02:00
New Revision: 712de9d1716c010e895a578ad86cbd47680a4fdd
URL: https://github.com/llvm/llvm-project/commit/712de9d1716c010e895a578ad86cbd47680a4fdd
DIFF: https://github.com/llvm/llvm-project/commit/712de9d1716c010e895a578ad86cbd47680a4fdd.diff
LOG: [AArch64] Add all predecessor archs in target info
A given function is compatible with all previous arch versions.
To avoid compering values of the attribute this logic adds all predecessor
architecture values.
Reviewed By: dmgreen, DavidSpickett
Differential Revision: https://reviews.llvm.org/D134353
Added:
clang/test/CodeGen/aarch64-subarch-compatbility.c
Modified:
clang/lib/Basic/Targets/AArch64.cpp
clang/lib/Basic/Targets/AArch64.h
llvm/include/llvm/Support/AArch64TargetParser.def
llvm/include/llvm/Support/AArch64TargetParser.h
llvm/lib/Support/AArch64TargetParser.cpp
llvm/unittests/Support/TargetParserTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index e8745402b58f..604c7bbb8153 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -529,6 +529,22 @@ bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
.Default(false);
}
+void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
+ StringRef Name, bool Enabled) const {
+ Features[Name] = Enabled;
+ llvm::AArch64::ArchKind AK = llvm::AArch64::getSubArchArchKind(Name);
+ // Add all previous architecture versions.
+ // In case of v9.x the v8.x counterparts are added too.
+ if ("9" == getArchVersionString(AK))
+ for (llvm::AArch64::ArchKind I = llvm::AArch64::convertV9toV8(AK);
+ I != llvm::AArch64::ArchKind::INVALID; --I)
+ Features[llvm::AArch64::getSubArch(I)] = Enabled;
+
+ for (llvm::AArch64::ArchKind I = --AK; I != llvm::AArch64::ArchKind::INVALID;
+ --I)
+ Features[llvm::AArch64::getSubArch(I)] = Enabled;
+}
+
bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
DiagnosticsEngine &Diags) {
FPU = FPUMode;
@@ -620,31 +636,32 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasSM4 = true;
if (Feature == "+strict-align")
HasUnaligned = false;
- if (Feature == "+v8a")
+ // All predecessor archs are added but select the latest one for ArchKind.
+ if (Feature == "+v8a" && ArchKind < llvm::AArch64::ArchKind::ARMV8A)
ArchKind = llvm::AArch64::ArchKind::ARMV8A;
- if (Feature == "+v8.1a")
+ if (Feature == "+v8.1a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_1A)
ArchKind = llvm::AArch64::ArchKind::ARMV8_1A;
- if (Feature == "+v8.2a")
+ if (Feature == "+v8.2a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_2A)
ArchKind = llvm::AArch64::ArchKind::ARMV8_2A;
- if (Feature == "+v8.3a")
+ if (Feature == "+v8.3a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_3A)
ArchKind = llvm::AArch64::ArchKind::ARMV8_3A;
- if (Feature == "+v8.4a")
+ if (Feature == "+v8.4a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_4A)
ArchKind = llvm::AArch64::ArchKind::ARMV8_4A;
- if (Feature == "+v8.5a")
+ if (Feature == "+v8.5a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_5A)
ArchKind = llvm::AArch64::ArchKind::ARMV8_5A;
- if (Feature == "+v8.6a")
+ if (Feature == "+v8.6a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_6A)
ArchKind = llvm::AArch64::ArchKind::ARMV8_6A;
- if (Feature == "+v8.7a")
+ if (Feature == "+v8.7a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_7A)
ArchKind = llvm::AArch64::ArchKind::ARMV8_7A;
- if (Feature == "+v8.8a")
+ if (Feature == "+v8.8a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_8A)
ArchKind = llvm::AArch64::ArchKind::ARMV8_8A;
- if (Feature == "+v9a")
+ if (Feature == "+v9a" && ArchKind < llvm::AArch64::ArchKind::ARMV9A)
ArchKind = llvm::AArch64::ArchKind::ARMV9A;
- if (Feature == "+v9.1a")
+ if (Feature == "+v9.1a" && ArchKind < llvm::AArch64::ArchKind::ARMV9_1A)
ArchKind = llvm::AArch64::ArchKind::ARMV9_1A;
- if (Feature == "+v9.2a")
+ if (Feature == "+v9.2a" && ArchKind < llvm::AArch64::ArchKind::ARMV9_2A)
ArchKind = llvm::AArch64::ArchKind::ARMV9_2A;
- if (Feature == "+v9.3a")
+ if (Feature == "+v9.3a" && ArchKind < llvm::AArch64::ArchKind::ARMV9_3A)
ArchKind = llvm::AArch64::ArchKind::ARMV9_3A;
if (Feature == "+v8r")
ArchKind = llvm::AArch64::ArchKind::ARMV8R;
diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h
index 1930092c248b..302cab409745 100644
--- a/clang/lib/Basic/Targets/AArch64.h
+++ b/clang/lib/Basic/Targets/AArch64.h
@@ -114,6 +114,8 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
getVScaleRange(const LangOptions &LangOpts) const override;
bool hasFeature(StringRef Feature) const override;
+ void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
+ bool Enabled) const override;
bool handleTargetFeatures(std::vector<std::string> &Features,
DiagnosticsEngine &Diags) override;
diff --git a/clang/test/CodeGen/aarch64-subarch-compatbility.c b/clang/test/CodeGen/aarch64-subarch-compatbility.c
new file mode 100644
index 000000000000..7c760f6b07a8
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-subarch-compatbility.c
@@ -0,0 +1,71 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang -target aarch64-none-linux -march=armv9.3-a -o %t -c %s 2>&1 | FileCheck --allow-empty %s
+
+// Successor targets should be ableto call predecessor target functions.
+__attribute__((__always_inline__,target("v8a")))
+int armv80(int i) {
+ return i + 42;
+}
+
+__attribute__((__always_inline__,target("v8.1a")))
+int armv81(int i) {
+ return armv80(i);
+}
+
+__attribute__((__always_inline__,target("v8.2a")))
+int armv82(int i) {
+ return armv81(i);
+}
+
+__attribute__((__always_inline__,target("v8.3a")))
+int armv83(int i) {
+ return armv82(i);
+}
+
+__attribute__((__always_inline__,target("v8.4a")))
+int armv84(int i) {
+ return armv83(i);
+}
+
+__attribute__((__always_inline__,target("v8.5a")))
+int armv85(int i) {
+ return armv84(i);
+}
+
+__attribute__((__always_inline__,target("v8.6a")))
+int armv86(int i) {
+ return armv85(i);
+}
+
+__attribute__((__always_inline__,target("v8.7a")))
+int armv87(int i) {
+ return armv86(i);
+}
+
+__attribute__((__always_inline__,target("v8.8a")))
+int armv88(int i) {
+ return armv87(i);
+}
+
+__attribute__((__always_inline__,target("v9a")))
+int armv9(int i) {
+ return armv85(i);
+}
+
+__attribute__((__always_inline__,target("v9.1a")))
+int armv91(int i) {
+ return armv9(i);
+}
+
+__attribute__((__always_inline__,target("v9.2a")))
+int armv92(int i) {
+ return armv91(i);
+}
+
+__attribute__((__always_inline__,target("v9.3a")))
+int armv93(int i) {
+ return armv92(i);
+}
+
+// CHECK-NOT: always_inline function {{.*}} requires target feature {{.*}}, but would be inlined into function {{.*}} that is compiled without support for {{.*}}
+// CHECK-NOT: {{.*}} is not a recognized feature for this target
diff --git a/llvm/include/llvm/Support/AArch64TargetParser.def b/llvm/include/llvm/Support/AArch64TargetParser.def
index c11a1a98c00d..d0a4551aff7d 100644
--- a/llvm/include/llvm/Support/AArch64TargetParser.def
+++ b/llvm/include/llvm/Support/AArch64TargetParser.def
@@ -15,6 +15,8 @@
#ifndef AARCH64_ARCH
#define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT)
#endif
+// NOTE: The order and the grouping of the elements matter to make ArchKind iterable.
+// List is organised as armv8a -> armv8n-a, armv9a -> armv9m-a and armv8-r.
AARCH64_ARCH("invalid", INVALID, "", "",
ARMBuildAttrs::CPUArch::v8_A, FK_NONE, AArch64::AEK_NONE)
AARCH64_ARCH("armv8-a", ARMV8A, "8-A", "v8a", ARMBuildAttrs::CPUArch::v8_A,
diff --git a/llvm/include/llvm/Support/AArch64TargetParser.h b/llvm/include/llvm/Support/AArch64TargetParser.h
index f1f985016ed8..1065b858ab5d 100644
--- a/llvm/include/llvm/Support/AArch64TargetParser.h
+++ b/llvm/include/llvm/Support/AArch64TargetParser.h
@@ -113,6 +113,17 @@ const ArchKind ArchKinds[] = {
#include "AArch64TargetParser.def"
};
+inline ArchKind &operator--(ArchKind &Kind) {
+ if ((Kind == ArchKind::INVALID) || (Kind == ArchKind::ARMV8A) ||
+ (Kind == ArchKind::ARMV9A) || (Kind == ArchKind::ARMV8R))
+ Kind = ArchKind::INVALID;
+ else {
+ unsigned KindAsInteger = static_cast<unsigned>(Kind);
+ Kind = static_cast<ArchKind>(--KindAsInteger);
+ }
+ return Kind;
+}
+
// FIXME: These should be moved to TargetTuple once it exists
bool getExtensionFeatures(uint64_t Extensions,
std::vector<StringRef> &Features);
@@ -124,12 +135,14 @@ StringRef getCPUAttr(ArchKind AK);
StringRef getSubArch(ArchKind AK);
StringRef getArchExtName(unsigned ArchExtKind);
StringRef getArchExtFeature(StringRef ArchExt);
+ArchKind convertV9toV8(ArchKind AK);
// Information by Name
unsigned getDefaultFPU(StringRef CPU, ArchKind AK);
uint64_t getDefaultExtensions(StringRef CPU, ArchKind AK);
StringRef getDefaultCPU(StringRef Arch);
ArchKind getCPUArchKind(StringRef CPU);
+ArchKind getSubArchArchKind(StringRef SubArch);
// Parser
ArchKind parseArch(StringRef Arch);
diff --git a/llvm/lib/Support/AArch64TargetParser.cpp b/llvm/lib/Support/AArch64TargetParser.cpp
index b0d5c205864f..cb06f6146be1 100644
--- a/llvm/lib/Support/AArch64TargetParser.cpp
+++ b/llvm/lib/Support/AArch64TargetParser.cpp
@@ -59,6 +59,15 @@ AArch64::ArchKind AArch64::getCPUArchKind(StringRef CPU) {
.Default(ArchKind::INVALID);
}
+AArch64::ArchKind AArch64::getSubArchArchKind(StringRef SubArch) {
+ return StringSwitch<AArch64::ArchKind>(SubArch)
+#define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, \
+ ARCH_BASE_EXT) \
+ .Case(SUB_ARCH, ArchKind::ID)
+#include "../../include/llvm/Support/AArch64TargetParser.def"
+ .Default(ArchKind::INVALID);
+}
+
bool AArch64::getExtensionFeatures(uint64_t Extensions,
std::vector<StringRef> &Features) {
if (Extensions == AArch64::AEK_INVALID)
@@ -123,6 +132,19 @@ StringRef AArch64::getArchExtFeature(StringRef ArchExt) {
return StringRef();
}
+AArch64::ArchKind AArch64::convertV9toV8(AArch64::ArchKind AK) {
+ if (AK == AArch64::ArchKind::INVALID)
+ return AK;
+ if (AK < AArch64::ArchKind::ARMV9A)
+ return AK;
+ if (AK >= AArch64::ArchKind::ARMV8R)
+ return AArch64::ArchKind::INVALID;
+ unsigned AK_v8 = static_cast<unsigned>(AArch64::ArchKind::ARMV8_5A);
+ AK_v8 += static_cast<unsigned>(AK) -
+ static_cast<unsigned>(AArch64::ArchKind::ARMV9A);
+ return static_cast<AArch64::ArchKind>(AK_v8);
+}
+
StringRef AArch64::getDefaultCPU(StringRef Arch) {
ArchKind AK = parseArch(Arch);
if (AK == ArchKind::INVALID)
diff --git a/llvm/unittests/Support/TargetParserTest.cpp b/llvm/unittests/Support/TargetParserTest.cpp
index f25b72efe601..06008ee0f264 100644
--- a/llvm/unittests/Support/TargetParserTest.cpp
+++ b/llvm/unittests/Support/TargetParserTest.cpp
@@ -1584,6 +1584,27 @@ TEST(TargetParserTest, AArch64ArchFeatures) {
}
}
+TEST(TargetParserTest, AArch64ArchV9toV8Conversion) {
+ for (auto AK : AArch64::ArchKinds) {
+ if (AK == AArch64::ArchKind::INVALID)
+ EXPECT_EQ(AK, AArch64::convertV9toV8(AK));
+ else if (AK < AArch64::ArchKind::ARMV9A)
+ EXPECT_EQ(AK, AArch64::convertV9toV8(AK));
+ else if (AK >= AArch64::ArchKind::ARMV8R)
+ EXPECT_EQ(AArch64::ArchKind::INVALID, AArch64::convertV9toV8(AK));
+ else
+ EXPECT_TRUE(AArch64::convertV9toV8(AK) < AArch64::ArchKind::ARMV9A);
+ }
+ EXPECT_EQ(AArch64::ArchKind::ARMV8_5A,
+ AArch64::convertV9toV8(AArch64::ArchKind::ARMV9A));
+ EXPECT_EQ(AArch64::ArchKind::ARMV8_6A,
+ AArch64::convertV9toV8(AArch64::ArchKind::ARMV9_1A));
+ EXPECT_EQ(AArch64::ArchKind::ARMV8_7A,
+ AArch64::convertV9toV8(AArch64::ArchKind::ARMV9_2A));
+ EXPECT_EQ(AArch64::ArchKind::ARMV8_8A,
+ AArch64::convertV9toV8(AArch64::ArchKind::ARMV9_3A));
+}
+
TEST(TargetParserTest, AArch64ArchExtFeature) {
const char *ArchExt[][4] = {
{"crc", "nocrc", "+crc", "-crc"},
More information about the cfe-commits
mailing list