Skip to content

Commit 0c0127b

Browse files
committed
[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
1 parent 85865f9 commit 0c0127b

File tree

4 files changed

+68
-15
lines changed

4 files changed

+68
-15
lines changed

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -736,17 +736,33 @@ bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
736736
void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
737737
StringRef Name, bool Enabled) const {
738738
Features[Name] = Enabled;
739+
740+
// If the feature is an architecture feature (like v8.2a), add all previous
741+
// architecture versions and any dependant target features.
739742
llvm::AArch64::ArchKind AK = llvm::AArch64::getSubArchArchKind(Name);
740-
// Add all previous architecture versions.
743+
if (AK == llvm::AArch64::ArchKind::INVALID)
744+
return;
741745
// In case of v9.x the v8.x counterparts are added too.
742746
if ("9" == getArchVersionString(AK))
743747
for (llvm::AArch64::ArchKind I = llvm::AArch64::convertV9toV8(AK);
744748
I != llvm::AArch64::ArchKind::INVALID; --I)
745749
Features[llvm::AArch64::getSubArch(I)] = Enabled;
746750

747-
for (llvm::AArch64::ArchKind I = --AK; I != llvm::AArch64::ArchKind::INVALID;
748-
--I)
751+
llvm::AArch64::ArchKind I = AK;
752+
for (--I; I != llvm::AArch64::ArchKind::INVALID; --I)
749753
Features[llvm::AArch64::getSubArch(I)] = Enabled;
754+
755+
// Set any features implied by the architecture
756+
uint64_t Extensions = llvm::AArch64::getDefaultExtensions("generic", AK);
757+
std::vector<StringRef> CPUFeats;
758+
if (llvm::AArch64::getExtensionFeatures(Extensions, CPUFeats)) {
759+
for (auto F : CPUFeats) {
760+
assert(F[0] == '+' && "Expected + in target feature!");
761+
if (F == "+crypto")
762+
continue;
763+
Features[F.drop_front(1)] = true;
764+
}
765+
}
750766
}
751767

752768
bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: %clang_cc1 -triple aarch64-eabi -target-feature +v8a -verify -DHAS8 -S %s -o -
2+
// RUN: %clang_cc1 -triple aarch64-eabi -target-feature +v8.1a -verify -DHAS81 -S %s -o -
3+
// RUN: %clang_cc1 -triple aarch64-eabi -target-feature +v9a -verify -DHAS9 -S %s -o -
4+
5+
#ifdef HAS9
6+
// expected-no-diagnostics
7+
#endif
8+
9+
#include <arm_acle.h>
10+
#include <arm_sve.h>
11+
12+
__attribute__((target("arch=armv8.1-a")))
13+
int test_crc_attr()
14+
{
15+
return __crc32cd(1, 1);
16+
}
17+
18+
__attribute__((target("arch=armv9-a")))
19+
svint8_t test_svadd_attr(svbool_t pg, svint8_t op1, svint8_t op2)
20+
{
21+
return svadd_s8_z(pg, op1, op2);
22+
}
23+
24+
svint8_t test_errors(svbool_t pg, svint8_t op1, svint8_t op2)
25+
{
26+
#ifdef HAS8
27+
// expected-error@+2{{always_inline function '__crc32cd' requires target feature 'crc'}}
28+
#endif
29+
__crc32cd(1, 1);
30+
#if defined(HAS8) || defined(HAS81)
31+
// expected-error@+2{{'svadd_s8_z' needs target feature sve}}
32+
#endif
33+
return svadd_s8_z(pg, op1, op2);
34+
}

clang/test/CodeGen/aarch64-targetattr.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ void noneon() {}
8989
__attribute__((target("no-simd")))
9090
void nosimd() {}
9191

92-
// CHECK: attributes #0 = { {{.*}} "target-features"="+v8.1a,+v8.2a,+v8a" }
93-
// CHECK: attributes #1 = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+v8.1a,+v8.2a,+v8a" }
94-
// CHECK: attributes #2 = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2,+v8.1a,+v8.2a,+v8a" }
95-
// CHECK: attributes #3 = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" }
92+
// CHECK: attributes #0 = { {{.*}} "target-features"="+crc,+fp-armv8,+lse,+neon,+ras,+rdm,+v8.1a,+v8.2a,+v8a" }
93+
// CHECK: attributes #1 = { {{.*}} "target-features"="+crc,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sve,+v8.1a,+v8.2a,+v8a" }
94+
// CHECK: attributes #2 = { {{.*}} "target-features"="+crc,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sve,+sve2,+v8.1a,+v8.2a,+v8a" }
95+
// 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" }
9696
// 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" }
9797
// CHECK: attributes #5 = { {{.*}} "tune-cpu"="cortex-a710" }
9898
// CHECK: attributes #6 = { {{.*}} "target-cpu"="generic" }
@@ -104,6 +104,6 @@ void nosimd() {}
104104
// CHECK: attributes #12 = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+sve" }
105105
// CHECK: attributes #13 = { {{.*}} "target-features"="+fp-armv8,+fullfp16,+neon,+sve,-sve2" }
106106
// CHECK: attributes #14 = { {{.*}} "target-features"="+fullfp16" }
107-
// 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" }
108-
// 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" }
107+
// 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" }
108+
// 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" }
109109
// CHECK: attributes #17 = { {{.*}} "target-features"="-neon" }

llvm/include/llvm/TargetParser/AArch64TargetParser.def

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,28 +69,31 @@ AARCH64_ARCH("armv9-a", ARMV9A, "+v9a",
6969
(AArch64::AEK_CRC | AArch64::AEK_FP |
7070
AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
7171
AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
72-
AArch64::AEK_SVE2))
72+
AArch64::AEK_SVE | AArch64::AEK_SVE2))
7373
AARCH64_ARCH("armv9.1-a", ARMV9_1A, "+v9.1a",
7474
(AArch64::AEK_CRC | AArch64::AEK_FP |
7575
AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
7676
AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
77-
AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE2))
77+
AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE |
78+
AArch64::AEK_SVE2))
7879
AARCH64_ARCH("armv9.2-a", ARMV9_2A, "+v9.2a",
7980
(AArch64::AEK_CRC | AArch64::AEK_FP |
8081
AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
8182
AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
82-
AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE2))
83+
AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE |
84+
AArch64::AEK_SVE2))
8385
AARCH64_ARCH("armv9.3-a", ARMV9_3A, "+v9.3a",
8486
(AArch64::AEK_CRC | AArch64::AEK_FP |
8587
AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
8688
AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
87-
AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE2))
89+
AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE |
90+
AArch64::AEK_SVE2))
8891
AARCH64_ARCH("armv9.4-a", ARMV9_4A, "+v9.4a",
8992
(AArch64::AEK_CRC | AArch64::AEK_FP |
9093
AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
9194
AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
92-
AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE2 |
93-
AArch64::AEK_RASv2))
95+
AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE |
96+
AArch64::AEK_SVE2 | AArch64::AEK_RASv2))
9497
// For v8-R, we do not enable crypto and align with GCC that enables a more
9598
// minimal set of optional architecture extensions.
9699
AARCH64_ARCH("armv8-r", ARMV8R, "+v8r",

0 commit comments

Comments
 (0)