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,
__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" }
// 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" }
(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",