Author: Jack Styles Date: 2025-04-29T08:28:10+01:00 New Revision: ace8ceab736f7e265b206b583d218a7554bee864
URL: https://github.com/llvm/llvm-project/commit/ace8ceab736f7e265b206b583d218a7554bee864 DIFF: https://github.com/llvm/llvm-project/commit/ace8ceab736f7e265b206b583d218a7554bee864.diff LOG: [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. Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Driver/ToolChains/Arch/ARM.cpp clang/test/Driver/arm-features.c clang/test/Driver/arm-mfpu.c clang/test/Preprocessor/arm-target-features.c Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 3105d8b481560..0fc46fe10b585 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -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. diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp index 5084058b3fef0..b6b1c2e28a96c 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -781,6 +781,22 @@ llvm::ARM::FPUKind arm::getARMTargetFeatures(const Driver &D, 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 @@ llvm::ARM::FPUKind arm::getARMTargetFeatures(const Driver &D, // 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 @@ llvm::ARM::FPUKind arm::getARMTargetFeatures(const Driver &D, 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 @@ llvm::ARM::FPUKind arm::getARMTargetFeatures(const Driver &D, 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( diff --git a/clang/test/Driver/arm-features.c b/clang/test/Driver/arm-features.c index eb424f5f61116..830bd54198e99 100644 --- a/clang/test/Driver/arm-features.c +++ b/clang/test/Driver/arm-features.c @@ -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" diff --git a/clang/test/Driver/arm-mfpu.c b/clang/test/Driver/arm-mfpu.c index 640e1b35c84b8..b97cc7bf12545 100644 --- a/clang/test/Driver/arm-mfpu.c +++ b/clang/test/Driver/arm-mfpu.c @@ -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 diff --git a/clang/test/Preprocessor/arm-target-features.c b/clang/test/Preprocessor/arm-target-features.c index 7b2a0ecdf9040..0f9063a27371e 100644 --- a/clang/test/Preprocessor/arm-target-features.c +++ b/clang/test/Preprocessor/arm-target-features.c @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits