[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