mirror of
https://github.com/intel/llvm.git
synced 2026-01-15 12:25:46 +08:00
[ARM][Driver] Ensure NEON is enabled and disabled correctly (#137595)
In #130623 support was added for `+nosimd` in the clang driver. Following this PR, it was discovered that, if NEON is disabled in the command line, it did not disable features that depend on this, such as Crypto or AES. To achieve this, This PR does the following: - Ensure that disabling NEON (e.g., via +nosimd) also disables dependent features like Crypto and AES. - Update the driver to automatically enable NEON when enabling features that require it (e.g., AES). This fixes inconsistent behavior where features relying on NEON could be enabled without NEON itself being active, or where disabling NEON left dependent features incorrectly enabled.
This commit is contained in:
@@ -608,6 +608,8 @@ Arm and AArch64 Support
|
||||
- The ``+nosimd`` attribute is now fully supported for ARM. Previously, this had no effect when being used with
|
||||
ARM targets, however this will now disable NEON instructions being generated. The ``simd`` option is
|
||||
also now printed when the ``--print-supported-extensions`` option is used.
|
||||
- When a feature that depends on NEON (``simd``) is used, NEON is now automatically enabled.
|
||||
- When NEON is disabled (``+nosimd``), all features that depend on NEON will now be disabled.
|
||||
|
||||
- Support for __ptrauth type qualifier has been added.
|
||||
|
||||
|
||||
@@ -781,6 +781,22 @@ fp16_fml_fallthrough:
|
||||
if (FPUKind == llvm::ARM::FK_FPV5_D16 || FPUKind == llvm::ARM::FK_FPV5_SP_D16)
|
||||
Features.push_back("-mve.fp");
|
||||
|
||||
// If SIMD has been disabled and the selected FPU supports NEON, then features
|
||||
// that rely on NEON instructions should also be disabled.
|
||||
bool HasSimd = false;
|
||||
const auto ItSimd =
|
||||
llvm::find_if(llvm::reverse(Features),
|
||||
[](const StringRef F) { return F.contains("neon"); });
|
||||
const bool FPUSupportsNeon = (llvm::ARM::FPUNames[FPUKind].NeonSupport ==
|
||||
llvm::ARM::NeonSupportLevel::Neon) ||
|
||||
(llvm::ARM::FPUNames[FPUKind].NeonSupport ==
|
||||
llvm::ARM::NeonSupportLevel::Crypto);
|
||||
if (ItSimd != Features.rend())
|
||||
HasSimd = ItSimd->starts_with("+");
|
||||
if (!HasSimd && FPUSupportsNeon)
|
||||
Features.insert(Features.end(),
|
||||
{"-sha2", "-aes", "-crypto", "-dotprod", "-bf16", "-imm8"});
|
||||
|
||||
// For Arch >= ARMv8.0 && A or R profile: crypto = sha2 + aes
|
||||
// Rather than replace within the feature vector, determine whether each
|
||||
// algorithm is enabled and append this to the end of the vector.
|
||||
@@ -791,6 +807,9 @@ fp16_fml_fallthrough:
|
||||
// FIXME: this needs reimplementation after the TargetParser rewrite
|
||||
bool HasSHA2 = false;
|
||||
bool HasAES = false;
|
||||
bool HasBF16 = false;
|
||||
bool HasDotprod = false;
|
||||
bool HasI8MM = false;
|
||||
const auto ItCrypto =
|
||||
llvm::find_if(llvm::reverse(Features), [](const StringRef F) {
|
||||
return F.contains("crypto");
|
||||
@@ -803,12 +822,25 @@ fp16_fml_fallthrough:
|
||||
llvm::find_if(llvm::reverse(Features), [](const StringRef F) {
|
||||
return F.contains("crypto") || F.contains("aes");
|
||||
});
|
||||
const bool FoundSHA2 = ItSHA2 != Features.rend();
|
||||
const bool FoundAES = ItAES != Features.rend();
|
||||
if (FoundSHA2)
|
||||
HasSHA2 = ItSHA2->take_front() == "+";
|
||||
if (FoundAES)
|
||||
HasAES = ItAES->take_front() == "+";
|
||||
const auto ItBF16 =
|
||||
llvm::find_if(llvm::reverse(Features),
|
||||
[](const StringRef F) { return F.contains("bf16"); });
|
||||
const auto ItDotprod =
|
||||
llvm::find_if(llvm::reverse(Features),
|
||||
[](const StringRef F) { return F.contains("dotprod"); });
|
||||
const auto ItI8MM =
|
||||
llvm::find_if(llvm::reverse(Features),
|
||||
[](const StringRef F) { return F.contains("i8mm"); });
|
||||
if (ItSHA2 != Features.rend())
|
||||
HasSHA2 = ItSHA2->starts_with("+");
|
||||
if (ItAES != Features.rend())
|
||||
HasAES = ItAES->starts_with("+");
|
||||
if (ItBF16 != Features.rend())
|
||||
HasBF16 = ItBF16->starts_with("+");
|
||||
if (ItDotprod != Features.rend())
|
||||
HasDotprod = ItDotprod->starts_with("+");
|
||||
if (ItI8MM != Features.rend())
|
||||
HasI8MM = ItI8MM->starts_with("+");
|
||||
if (ItCrypto != Features.rend()) {
|
||||
if (HasSHA2 && HasAES)
|
||||
Features.push_back("+crypto");
|
||||
@@ -823,6 +855,9 @@ fp16_fml_fallthrough:
|
||||
else
|
||||
Features.push_back("-aes");
|
||||
}
|
||||
// If any of these features are enabled, NEON should also be enabled.
|
||||
if (HasAES || HasSHA2 || HasBF16 || HasDotprod || HasI8MM)
|
||||
Features.push_back("+neon");
|
||||
|
||||
if (HasSHA2 || HasAES) {
|
||||
StringRef ArchSuffix = arm::getLLVMArchSuffixForARM(
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
// Check +crypto for M and R profiles:
|
||||
//
|
||||
// RUN: %clang -target arm-arm-none-eabi -march=armv8-r+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO-R %s
|
||||
// CHECK-CRYPTO-R: "-cc1"{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "+sha2" "-target-feature" "+aes"
|
||||
// CHECK-CRYPTO-R: "-cc1"{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "+sha2" "-target-feature" "+aes" "-target-feature" "+neon"
|
||||
// RUN: %clang -target arm-arm-none-eabi -march=armv8-m.base+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO5 %s
|
||||
// RUN: %clang -target arm-arm-none-eabi -march=armv8-m.main+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO5 %s
|
||||
// RUN: %clang -target arm-arm-none-eabi -mcpu=cortex-m23+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO5 %s
|
||||
@@ -97,3 +97,11 @@
|
||||
// CHECK-NOSHA-DAG: "-target-feature" "-sha2"
|
||||
// CHECK-NOAES-DAG: "-target-feature" "-aes"
|
||||
//
|
||||
// Check that adding features that depend on NEON enable the feature
|
||||
// RUN: %clang -target arm-none-none-eabi -march=armv8-r+sha2 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NEON-ENABLED-WITH-FEATURE %s
|
||||
// RUN: %clang -target arm-none-none-eabi -march=armv8-r+aes -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NEON-ENABLED-WITH-FEATURE %s
|
||||
// RUN: %clang -target arm-none-none-eabi -march=armv8-r+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NEON-ENABLED-WITH-FEATURE %s
|
||||
// RUN: %clang -target arm-none-none-eabi -march=armv8-r+dotprod -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NEON-ENABLED-WITH-FEATURE %s
|
||||
// RUN: %clang -target arm-none-none-eabi -march=armv8-r+bf16 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NEON-ENABLED-WITH-FEATURE %s
|
||||
// RUN: %clang -target arm-none-none-eabi -march=armv8-r+i8mm -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NEON-ENABLED-WITH-FEATURE %s
|
||||
// CHECK-NEON-ENABLED-WITH-FEATURE: "-target-feature" "+neon"
|
||||
|
||||
@@ -407,7 +407,7 @@
|
||||
// CHECK-ARM8-ANDROID-FP-DEFAULT-DAG: "-target-feature" "+fp-armv8"
|
||||
// CHECK-ARM8-ANDROID-FP-DEFAULT-DAG: "-target-feature" "+aes"
|
||||
// CHECK-ARM8-ANDROID-FP-DEFAULT-DAG: "-target-feature" "+sha2"
|
||||
// CHECK-ARM8-ANDROID-FP-DEFAULT-NOT: "-target-feature" "+neon"
|
||||
// CHECK-ARM8-ANDROID-FP-DEFAULT-DAG: "-target-feature" "+neon"
|
||||
|
||||
// RUN: %clang -target armv8-linux-android %s -### -c 2>&1 \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-ARM8-ANDROID-DEFAULT %s
|
||||
@@ -416,7 +416,7 @@
|
||||
// CHECK-ARM8-ANDROID-DEFAULT-DAG: "-target-feature" "+fp-armv8"
|
||||
// CHECK-ARM8-ANDROID-DEFAULT-DAG: "-target-feature" "+aes"
|
||||
// CHECK-ARM8-ANDROID-DEFAULT-DAG: "-target-feature" "+sha2"
|
||||
// CHECK-ARM8-ANDROID-DEFAULT-NOT: "-target-feature" "+neon"
|
||||
// CHECK-ARM8-ANDROID-DEFAULT-DAG: "-target-feature" "+neon"
|
||||
|
||||
// RUN: %clang -target armv7-linux-androideabi21 %s -mfpu=vfp3-d16 -### -c 2>&1 \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-ARM7-ANDROID-FP-D16 %s
|
||||
|
||||
@@ -1036,10 +1036,16 @@
|
||||
// CHECK-SIMD: #define __ARM_NEON_FP 0x6
|
||||
// CHECK-SIMD: #define __ARM_NEON__ 1
|
||||
|
||||
// Check that on AArch32 appropriate targets, +nosimd correctly disables NEON instructions.
|
||||
// RUN: %clang -target arm-none-eabi -march=armv8-a+nosimd -mfloat-abi=hard -x c -E -dM -o - %s | FileCheck -check-prefix=CHECK-NOSIMD %s
|
||||
// Check that on AArch32 appropriate targets, +nosimd correctly disables NEON instructions. All features that rely on NEON should also be disabled.
|
||||
// RUN: %clang -target arm-none-eabi -march=armv9.6-a+nosimd -mfloat-abi=hard -x c -E -dM -o - %s | FileCheck -check-prefix=CHECK-NOSIMD %s
|
||||
// RUN: %clang -target arm-none-eabi -mcpu=cortex-r52+nosimd -mfloat-abi=hard -x c -E -dM -o - %s | FileCheck -check-prefix=CHECK-NOSIMD %s
|
||||
// RUN: %clang -target arm-none-eabi -mcpu=cortex-a57+nosimd -mfloat-abi=hard -x c -E -dM -o - %s | FileCheck -check-prefix=CHECK-NOSIMD %s
|
||||
// CHECK-NOSIMD-NOT: #define __ARM_FEATURE_BF16 1
|
||||
// CHECK-NOSIMD-NOT: #define __ARM_FEATURE_BF16_VECTOR_ARITHMETIC 1
|
||||
// CHECK-NOSIMD-NOT: #define __ARM_FEATURE_AES 1
|
||||
// CHECK-NOSIMD-NOT: #define __ARM_FEATURE_CRYPTO 1
|
||||
// CHECK-NOSIMD-NOT: #define __ARM_FEATURE_DOTPROD 1
|
||||
// CHECK-NOSIMD-NOT: #define __ARM_FEATURE_SHA2 1
|
||||
// CHECK-NOSIMD-NOT: #define __ARM_NEON 1
|
||||
// CHECK-NOSIMD-NOT: #define __ARM_NEON_FP 0x6
|
||||
// CHECK-NOSIMD-NOT: #define __ARM_NEON__ 1
|
||||
|
||||
Reference in New Issue
Block a user