[clang] 0c0127b - [AArch64] Make -march and target(arch=..) attributes imply dependent features

David Green via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 11 00:48:29 PST 2023


Author: David Green
Date: 2023-01-11T08:48:23Z
New Revision: 0c0127bb9f0098752a9769748511e170ed240695

URL: https://github.com/llvm/llvm-project/commit/0c0127bb9f0098752a9769748511e170ed240695
DIFF: https://github.com/llvm/llvm-project/commit/0c0127bb9f0098752a9769748511e170ed240695.diff

LOG: [AArch64] Make -march and target(arch=..) attributes imply dependent features

Specifying an architecture revision should also add feature strings for
any dependent default extensions. Otherwise the new checks for
target-dependent features for acle intrinsics from D134353 and D132034
can fail.

This patch does that in setFeatureEnabled, similar to the addition of
dependent architecture revisions. +sve also needs to be added to armv9
architectures in the target parser, as it is implied by +sve2.

Fixes #59911

Differential Revision: https://reviews.llvm.org/D141411

Added: 
    clang/test/CodeGen/aarch64-targetattr-arch.c

Modified: 
    clang/lib/Basic/Targets/AArch64.cpp
    clang/test/CodeGen/aarch64-targetattr.c
    llvm/include/llvm/TargetParser/AArch64TargetParser.def

Removed: 
    


################################################################################
diff  --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index 5db313813a76a..a4b27bb64ab8d 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -736,17 +736,33 @@ bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
 void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
                                           StringRef Name, bool Enabled) const {
   Features[Name] = Enabled;
+
+  // If the feature is an architecture feature (like v8.2a), add all previous
+  // architecture versions and any dependant target features.
   llvm::AArch64::ArchKind AK = llvm::AArch64::getSubArchArchKind(Name);
-  // Add all previous architecture versions.
+  if (AK == llvm::AArch64::ArchKind::INVALID)
+    return;
   // 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)
+  llvm::AArch64::ArchKind I = AK;
+  for (--I; I != llvm::AArch64::ArchKind::INVALID; --I)
     Features[llvm::AArch64::getSubArch(I)] = Enabled;
+
+  // Set any features implied by the architecture
+  uint64_t Extensions = llvm::AArch64::getDefaultExtensions("generic", AK);
+  std::vector<StringRef> CPUFeats;
+  if (llvm::AArch64::getExtensionFeatures(Extensions, CPUFeats)) {
+    for (auto F : CPUFeats) {
+      assert(F[0] == '+' && "Expected + in target feature!");
+      if (F == "+crypto")
+        continue;
+      Features[F.drop_front(1)] = true;
+    }
+  }
 }
 
 bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,

diff  --git a/clang/test/CodeGen/aarch64-targetattr-arch.c b/clang/test/CodeGen/aarch64-targetattr-arch.c
new file mode 100644
index 0000000000000..059036dfcc6fc
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-targetattr-arch.c
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple aarch64-eabi -target-feature +v8a -verify -DHAS8 -S %s -o -
+// RUN: %clang_cc1 -triple aarch64-eabi -target-feature +v8.1a -verify -DHAS81 -S %s -o -
+// RUN: %clang_cc1 -triple aarch64-eabi -target-feature +v9a -verify -DHAS9 -S %s -o -
+
+#ifdef HAS9
+// expected-no-diagnostics
+#endif
+
+#include <arm_acle.h>
+#include <arm_sve.h>
+
+__attribute__((target("arch=armv8.1-a")))
+int test_crc_attr()
+{
+  return __crc32cd(1, 1);
+}
+
+__attribute__((target("arch=armv9-a")))
+svint8_t test_svadd_attr(svbool_t pg, svint8_t op1, svint8_t op2)
+{
+  return svadd_s8_z(pg, op1, op2);
+}
+
+svint8_t test_errors(svbool_t pg, svint8_t op1, svint8_t op2)
+{
+#ifdef HAS8
+// expected-error at +2{{always_inline function '__crc32cd' requires target feature 'crc'}}
+#endif
+  __crc32cd(1, 1);
+#if defined(HAS8) || defined(HAS81)
+// expected-error at +2{{'svadd_s8_z' needs target feature sve}}
+#endif
+  return svadd_s8_z(pg, op1, op2);
+}

diff  --git a/clang/test/CodeGen/aarch64-targetattr.c b/clang/test/CodeGen/aarch64-targetattr.c
index 88af5cc5bc8da..8730ecfbd1343 100644
--- a/clang/test/CodeGen/aarch64-targetattr.c
+++ b/clang/test/CodeGen/aarch64-targetattr.c
@@ -89,10 +89,10 @@ void noneon() {}
 __attribute__((target("no-simd")))
 void nosimd() {}
 
-// CHECK: attributes #0 = { {{.*}} "target-features"="+v8.1a,+v8.2a,+v8a" }
-// CHECK: attributes #1 = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+v8.1a,+v8.2a,+v8a" }
-// CHECK: attributes #2 = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2,+v8.1a,+v8.2a,+v8a" }
-// CHECK: attributes #3 = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" }
+// CHECK: attributes #0 = { {{.*}} "target-features"="+crc,+fp-armv8,+lse,+neon,+ras,+rdm,+v8.1a,+v8.2a,+v8a" }
+// CHECK: attributes #1 = { {{.*}} "target-features"="+crc,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sve,+v8.1a,+v8.2a,+v8a" }
+// CHECK: attributes #2 = { {{.*}} "target-features"="+crc,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sve,+sve2,+v8.1a,+v8.2a,+v8a" }
+// CHECK: attributes #3 = { {{.*}} "target-features"="+aes,+bf16,+crc,+dotprod,+fp-armv8,+fullfp16,+i8mm,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" }
 // CHECK: attributes #4 = { {{.*}} "target-cpu"="cortex-a710" "target-features"="+bf16,+crc,+dotprod,+flagm,+fp-armv8,+fp16fml,+i8mm,+lse,+mte,+neon,+pauth,+ras,+rcpc,+rdm,+sb,+sve,+sve2,+sve2-bitperm" }
 // CHECK: attributes #5 = { {{.*}} "tune-cpu"="cortex-a710" }
 // CHECK: attributes #6 = { {{.*}} "target-cpu"="generic" }
@@ -104,6 +104,6 @@ void nosimd() {}
 // CHECK: attributes #12 = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+sve" }
 // CHECK: attributes #13 = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+sve,-sve2" }
 // CHECK: attributes #14 = { {{.*}} "target-features"="+fullfp16" }
-// CHECK: attributes #15 = { {{.*}} "target-cpu"="neoverse-n1" "target-features"="+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" "tune-cpu"="cortex-a710" }
-// CHECK: attributes #16 = { {{.*}} "branch-target-enforcement"="true" {{.*}} "target-cpu"="neoverse-n1" "target-features"="+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" "tune-cpu"="cortex-a710" }
+// CHECK: attributes #15 = { {{.*}} "target-cpu"="neoverse-n1" "target-features"="+aes,+bf16,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+i8mm,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" "tune-cpu"="cortex-a710" }
+// CHECK: attributes #16 = { {{.*}} "branch-target-enforcement"="true" {{.*}} "target-features"="+aes,+bf16,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+i8mm,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" "tune-cpu"="cortex-a710" }
 // CHECK: attributes #17 = { {{.*}} "target-features"="-neon" }

diff  --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.def b/llvm/include/llvm/TargetParser/AArch64TargetParser.def
index e7fadc98a9c0d..570172ace990a 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.def
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.def
@@ -69,28 +69,31 @@ AARCH64_ARCH("armv9-a",   ARMV9A, "+v9a",
              (AArch64::AEK_CRC | AArch64::AEK_FP |
               AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
               AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
-              AArch64::AEK_SVE2))
+              AArch64::AEK_SVE | AArch64::AEK_SVE2))
 AARCH64_ARCH("armv9.1-a", ARMV9_1A, "+v9.1a",
              (AArch64::AEK_CRC | AArch64::AEK_FP |
               AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
               AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
-              AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE2))
+              AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE |
+              AArch64::AEK_SVE2))
 AARCH64_ARCH("armv9.2-a", ARMV9_2A, "+v9.2a",
              (AArch64::AEK_CRC | AArch64::AEK_FP |
               AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
               AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
-              AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE2))
+              AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE |
+              AArch64::AEK_SVE2))
 AARCH64_ARCH("armv9.3-a", ARMV9_3A, "+v9.3a",
              (AArch64::AEK_CRC | AArch64::AEK_FP |
               AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
               AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
-              AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE2))
+              AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE |
+              AArch64::AEK_SVE2))
 AARCH64_ARCH("armv9.4-a", ARMV9_4A, "+v9.4a",
              (AArch64::AEK_CRC | AArch64::AEK_FP |
               AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
               AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
-              AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE2 |
-              AArch64::AEK_RASv2))
+              AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE |
+              AArch64::AEK_SVE2 | AArch64::AEK_RASv2))
 // For v8-R, we do not enable crypto and align with GCC that enables a more
 // minimal set of optional architecture extensions.
 AARCH64_ARCH("armv8-r", ARMV8R, "+v8r",


        


More information about the cfe-commits mailing list