[clang] [llvm] [ARM][Clang] Make `+nosimd` functional for AArch32 Targets (PR #130623)
Jack Styles via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 11 02:39:42 PDT 2025
https://github.com/Stylie777 updated https://github.com/llvm/llvm-project/pull/130623
>From d6772d64ff6fd515621c073b6545c40e918893b5 Mon Sep 17 00:00:00 2001
From: Jack Styles <jack.styles at arm.com>
Date: Fri, 7 Mar 2025 15:51:34 +0000
Subject: [PATCH 1/3] [NFC][ARM] Split SIMD identifier away from MVE
Previously, the use of MVE or MVE.FP would be defined
by using the `ARM::AEK_SIMD` identifier. SIMD relates to
the Cortex-A and Cortex-R extension that enables NEON
instructions, which is called MVE for Cortex-M. To enable the
linking of `+simd` and `+nosimd` to `+neon` and `-neon`
when using clang, MVE and MVE.FP can now be defined
using a unique enum identifier, rather than using the existing
identifier for SIMD.
This was originally planned to be merged as part of #130296 but
the changes made `+nosimd` an invalid argument, which, while not
having any functionality, was allowed in previous versions of
LLVM. To avoid regressions being introduced, this has been
combined with the fix for `+nosimd` on AArch32.
---
llvm/include/llvm/TargetParser/ARMTargetParser.def | 10 +++++-----
llvm/include/llvm/TargetParser/ARMTargetParser.h | 1 +
llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 2 +-
llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp | 2 +-
llvm/unittests/TargetParser/TargetParserTest.cpp | 6 +++---
5 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/llvm/include/llvm/TargetParser/ARMTargetParser.def b/llvm/include/llvm/TargetParser/ARMTargetParser.def
index 6b96c3e83c8c4..e515ab665d117 100644
--- a/llvm/include/llvm/TargetParser/ARMTargetParser.def
+++ b/llvm/include/llvm/TargetParser/ARMTargetParser.def
@@ -224,8 +224,8 @@ ARM_ARCH_EXT_NAME("dotprod", ARM::AEK_DOTPROD, "+dotprod", "-dotprod")
ARM_ARCH_EXT_NAME("dsp", ARM::AEK_DSP, "+dsp", "-dsp")
ARM_ARCH_EXT_NAME("fp", ARM::AEK_FP, {}, {})
ARM_ARCH_EXT_NAME("fp.dp", ARM::AEK_FP_DP, {}, {})
-ARM_ARCH_EXT_NAME("mve", (ARM::AEK_DSP | ARM::AEK_SIMD), "+mve", "-mve")
-ARM_ARCH_EXT_NAME("mve.fp", (ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP),
+ARM_ARCH_EXT_NAME("mve", (ARM::AEK_DSP | ARM::AEK_MVE), "+mve", "-mve")
+ARM_ARCH_EXT_NAME("mve.fp", (ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP),
"+mve.fp", "-mve.fp")
ARM_ARCH_EXT_NAME("idiv", (ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB), {}, {})
ARM_ARCH_EXT_NAME("mp", ARM::AEK_MP, {}, {})
@@ -345,12 +345,12 @@ ARM_CPU_NAME("cortex-m33", ARMV8MMainline, FK_FPV5_SP_D16, false, ARM::AEK_DSP)
ARM_CPU_NAME("star-mc1", ARMV8MMainline, FK_FPV5_SP_D16, false, ARM::AEK_DSP)
ARM_CPU_NAME("cortex-m35p", ARMV8MMainline, FK_FPV5_SP_D16, false, ARM::AEK_DSP)
ARM_CPU_NAME("cortex-m55", ARMV8_1MMainline, FK_FP_ARMV8_FULLFP16_D16, false,
- (ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP | ARM::AEK_FP16))
+ (ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP | ARM::AEK_FP16))
ARM_CPU_NAME("cortex-m85", ARMV8_1MMainline, FK_FP_ARMV8_FULLFP16_D16, false,
- (ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP | ARM::AEK_FP16 |
+ (ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP | ARM::AEK_FP16 |
ARM::AEK_RAS | ARM::AEK_PACBTI))
ARM_CPU_NAME("cortex-m52", ARMV8_1MMainline, FK_FP_ARMV8_FULLFP16_D16, false,
- (ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP | ARM::AEK_FP16 |
+ (ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP | ARM::AEK_FP16 |
ARM::AEK_RAS | ARM::AEK_PACBTI))
ARM_CPU_NAME("cortex-a32", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
ARM_CPU_NAME("cortex-a35", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
diff --git a/llvm/include/llvm/TargetParser/ARMTargetParser.h b/llvm/include/llvm/TargetParser/ARMTargetParser.h
index 5dbcfd3d2d693..b2403f42f1b79 100644
--- a/llvm/include/llvm/TargetParser/ARMTargetParser.h
+++ b/llvm/include/llvm/TargetParser/ARMTargetParser.h
@@ -61,6 +61,7 @@ enum ArchExtKind : uint64_t {
AEK_CDECP6 = 1 << 28,
AEK_CDECP7 = 1 << 29,
AEK_PACBTI = 1 << 30,
+ AEK_MVE = 1ULL << 31,
// Unsupported extensions.
AEK_OS = 1ULL << 59,
AEK_IWMMXT = 1ULL << 60,
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index d6a586e1f247b..79b54e6b04330 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -12971,7 +12971,7 @@ bool ARMAsmParser::enableArchExtFeature(StringRef Name, SMLoc &ExtLoc) {
{ARM::AEK_CRYPTO,
{Feature_HasV8Bit},
{ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
- {(ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP),
+ {(ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP),
{Feature_HasV8_1MMainlineBit},
{ARM::HasMVEFloatOps}},
{ARM::AEK_FP,
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp
index b0fa03a35ec04..632dbebf58f04 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp
@@ -248,7 +248,7 @@ void ARMTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {
emitFPU(STI.hasFeature(ARM::FeatureFP64) ? ARM::FK_FPV5_D16
: ARM::FK_FPV5_SP_D16);
if (STI.hasFeature(ARM::HasMVEFloatOps))
- emitArchExtension(ARM::AEK_SIMD | ARM::AEK_DSP | ARM::AEK_FP);
+ emitArchExtension(ARM::AEK_MVE | ARM::AEK_DSP | ARM::AEK_FP);
}
} else if (STI.hasFeature(ARM::FeatureVFP4_D16_SP))
emitFPU(STI.hasFeature(ARM::FeatureD32)
diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index 5d771a1a153f7..574d69f847b4d 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -507,17 +507,17 @@ INSTANTIATE_TEST_SUITE_P(
"8-M.Mainline"),
ARMCPUTestParams<uint64_t>(
"cortex-m55", "armv8.1-m.main", "fp-armv8-fullfp16-d16",
- ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP |
+ ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP |
ARM::AEK_RAS | ARM::AEK_LOB | ARM::AEK_FP16,
"8.1-M.Mainline"),
ARMCPUTestParams<uint64_t>(
"cortex-m85", "armv8.1-m.main", "fp-armv8-fullfp16-d16",
- ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP |
+ ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP |
ARM::AEK_RAS | ARM::AEK_LOB | ARM::AEK_FP16 | ARM::AEK_PACBTI,
"8.1-M.Mainline"),
ARMCPUTestParams<uint64_t>(
"cortex-m52", "armv8.1-m.main", "fp-armv8-fullfp16-d16",
- ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP |
+ ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP |
ARM::AEK_RAS | ARM::AEK_LOB | ARM::AEK_FP16 | ARM::AEK_PACBTI,
"8.1-M.Mainline"),
ARMCPUTestParams<uint64_t>("iwmmxt", "iwmmxt", "none", ARM::AEK_NONE,
>From faa829ce032247c052dc08abbb3e3b3f54d0c19e Mon Sep 17 00:00:00 2001
From: Jack Styles <jack.styles at arm.com>
Date: Fri, 7 Mar 2025 15:49:00 +0000
Subject: [PATCH 2/3] [Clang][ARM] Enable the use of `+simd` and `+nosimd` for
AArch32 Targets
`+simd` and `+nosimd` are used to enable or disable NEON Instructions
when compiling for AArch32 Targets. However, up until now, using these
has not been possible. To enable this, these options are mapped to the
relevant LLVM backend option (`+neon` and `-neon`) so it can be both
enabled and disabled successfully by the user.
Tests have been added to ensure this behaviour is maintained in the future,
along with updates to existing tests as behaviour has now changed relating
to the use of `+simd` and `+nosimd`.
As `simd` has been mapped within the ARMTargetParser.def, support for this
extension is also added for the `--print-support-extensions` command when
the target is AArch32. This will print the `simd` option, along with the
description that relates to the Neon feature. This previously was not
possible as `simd` did not have a related Feature or Negative Feature.
---
.../test/Driver/print-supported-extensions-arm.c | 1 +
clang/test/Preprocessor/arm-target-features.c | 8 ++++++++
llvm/docs/ReleaseNotes.md | 3 +++
.../include/llvm/TargetParser/ARMTargetParser.def | 6 +++---
llvm/lib/TargetParser/ARMTargetParser.cpp | 4 ++++
llvm/unittests/TargetParser/TargetParserTest.cpp | 15 +++++++--------
6 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/clang/test/Driver/print-supported-extensions-arm.c b/clang/test/Driver/print-supported-extensions-arm.c
index 0dc2e9fc69738..407adc5e9c384 100644
--- a/clang/test/Driver/print-supported-extensions-arm.c
+++ b/clang/test/Driver/print-supported-extensions-arm.c
@@ -12,6 +12,7 @@
// CHECK-NEXT: dsp Supports DSP instructions in ARM and/or Thumb2
// CHECK-NEXT: mve Support M-Class Vector Extension with integer ops
// CHECK-NEXT: mve.fp Support M-Class Vector Extension with integer and floating ops
+// CHECK-NEXT: simd Enable NEON instructions
// CHECK-NEXT: fp16 Enable half-precision floating point
// CHECK-NEXT: ras Enable Reliability, Availability and Serviceability extensions
// CHECK-NEXT: fp16fml Enable full half-precision floating point fml instructions
diff --git a/clang/test/Preprocessor/arm-target-features.c b/clang/test/Preprocessor/arm-target-features.c
index 94dcfc2424bb1..b36dd1765b6de 100644
--- a/clang/test/Preprocessor/arm-target-features.c
+++ b/clang/test/Preprocessor/arm-target-features.c
@@ -1027,3 +1027,11 @@
// CHECK-R52-NEXT: #define __ARM_VFPV4__ 1
// CHECK-R52-NOT: #define __ARM_NEON 1
// CHECK-R52-NOT: #define __ARM_NEON__
+
+// 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
+// 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_NEON 1
+// CHECK-NOSIMD-NOT: #define __ARM_NEON_FP 0x6
+// CHECK-NOSIMD-NOT: #define __ARM_NEON__ 1
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index d7a80ae93aa34..43ed754183be7 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -85,6 +85,9 @@ Changes to the AMDGPU Backend
Changes to the ARM Backend
--------------------------
+* The `+nosimd` attribute is now fully supported. Previously, this had no effect when being used with
+AArch32 targets, however will now disable NEON instructions being generated. The `simd` is also now
+printed when the `--print-supported-extensions` option is used..
Changes to the AVR Backend
--------------------------
diff --git a/llvm/include/llvm/TargetParser/ARMTargetParser.def b/llvm/include/llvm/TargetParser/ARMTargetParser.def
index e515ab665d117..e8837cb89ed29 100644
--- a/llvm/include/llvm/TargetParser/ARMTargetParser.def
+++ b/llvm/include/llvm/TargetParser/ARMTargetParser.def
@@ -229,7 +229,7 @@ ARM_ARCH_EXT_NAME("mve.fp", (ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP),
"+mve.fp", "-mve.fp")
ARM_ARCH_EXT_NAME("idiv", (ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB), {}, {})
ARM_ARCH_EXT_NAME("mp", ARM::AEK_MP, {}, {})
-ARM_ARCH_EXT_NAME("simd", ARM::AEK_SIMD, {}, {})
+ARM_ARCH_EXT_NAME("simd", ARM::AEK_SIMD, "+neon", "-neon")
ARM_ARCH_EXT_NAME("sec", ARM::AEK_SEC, {}, {})
ARM_ARCH_EXT_NAME("virt", ARM::AEK_VIRT, {}, {})
ARM_ARCH_EXT_NAME("fp16", ARM::AEK_FP16, "+fullfp16", "-fullfp16")
@@ -334,8 +334,8 @@ ARM_CPU_NAME("cortex-r7", ARMV7R, FK_VFPV3_D16_FP16, false,
(ARM::AEK_MP | ARM::AEK_HWDIVARM))
ARM_CPU_NAME("cortex-r8", ARMV7R, FK_VFPV3_D16_FP16, false,
(ARM::AEK_MP | ARM::AEK_HWDIVARM))
-ARM_CPU_NAME("cortex-r52", ARMV8R, FK_NEON_FP_ARMV8, false, ARM::AEK_NONE)
-ARM_CPU_NAME("cortex-r52plus", ARMV8R, FK_NEON_FP_ARMV8, false, ARM::AEK_NONE)
+ARM_CPU_NAME("cortex-r52", ARMV8R, FK_NEON_FP_ARMV8, false, ARM::AEK_SIMD)
+ARM_CPU_NAME("cortex-r52plus", ARMV8R, FK_NEON_FP_ARMV8, false, ARM::AEK_SIMD)
ARM_CPU_NAME("sc300", ARMV7M, FK_NONE, false, ARM::AEK_NONE)
ARM_CPU_NAME("cortex-m3", ARMV7M, FK_NONE, true, ARM::AEK_NONE)
ARM_CPU_NAME("cortex-m4", ARMV7EM, FK_FPV4_SP_D16, true, ARM::AEK_NONE)
diff --git a/llvm/lib/TargetParser/ARMTargetParser.cpp b/llvm/lib/TargetParser/ARMTargetParser.cpp
index 8f9753775c204..a7a895d872668 100644
--- a/llvm/lib/TargetParser/ARMTargetParser.cpp
+++ b/llvm/lib/TargetParser/ARMTargetParser.cpp
@@ -657,6 +657,10 @@ void ARM::PrintSupportedExtensions(StringMap<StringRef> DescMap) {
// Extensions without a feature cannot be used with -march.
if (!Ext.Feature.empty()) {
std::string Description = DescMap[Ext.Name].str();
+ // With SIMD, this links to the NEON feature, so the description should be
+ // taken from here, as SIMD does not exist in TableGen.
+ if (Ext.Name == "simd")
+ Description = DescMap["neon"].str();
outs() << " "
<< format(Description.empty() ? "%s\n" : "%-20s%s\n",
Ext.Name.str().c_str(), Description.c_str());
diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index 574d69f847b4d..2a97d1c80ce8d 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -318,14 +318,14 @@ INSTANTIATE_TEST_SUITE_P(
ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
"7-R"),
ARMCPUTestParams<uint64_t>("cortex-r52", "armv8-r", "neon-fp-armv8",
- ARM::AEK_NONE | ARM::AEK_CRC | ARM::AEK_MP |
- ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
- ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+ ARM::AEK_CRC | ARM::AEK_MP | ARM::AEK_VIRT |
+ ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
+ ARM::AEK_DSP | ARM::AEK_SIMD,
"8-R"),
ARMCPUTestParams<uint64_t>("cortex-r52plus", "armv8-r", "neon-fp-armv8",
- ARM::AEK_NONE | ARM::AEK_CRC | ARM::AEK_MP |
- ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
- ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+ ARM::AEK_CRC | ARM::AEK_MP | ARM::AEK_VIRT |
+ ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
+ ARM::AEK_DSP | ARM::AEK_SIMD,
"8-R"),
ARMCPUTestParams<uint64_t>("sc300", "armv7-m", "none",
ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "7-M"),
@@ -801,7 +801,7 @@ TEST(TargetParserTest, ARMArchExtFeature) {
{"fp", "nofp", nullptr, nullptr},
{"idiv", "noidiv", nullptr, nullptr},
{"mp", "nomp", nullptr, nullptr},
- {"simd", "nosimd", nullptr, nullptr},
+ {"simd", "nosimd", "+neon", "-neon"},
{"sec", "nosec", nullptr, nullptr},
{"virt", "novirt", nullptr, nullptr},
{"fp16", "nofp16", "+fullfp16", "-fullfp16"},
@@ -1046,7 +1046,6 @@ TEST(TargetParserTest, ARMPrintSupportedExtensions) {
EXPECT_EQ(std::string::npos, captured.find("invalid"));
// Should not include anything that lacks a feature name. Checking a few here
// but not all as if one is hidden correctly the rest should be.
- EXPECT_EQ(std::string::npos, captured.find("simd"));
EXPECT_EQ(std::string::npos, captured.find("maverick"));
EXPECT_EQ(std::string::npos, captured.find("xscale"));
}
>From 8d28d1388567e8fc34fe296e4d3911c3e994ded5 Mon Sep 17 00:00:00 2001
From: Jack Styles <jack.styles at arm.com>
Date: Tue, 11 Mar 2025 09:35:15 +0000
Subject: [PATCH 3/3] Improve Release Notes
---
llvm/docs/ReleaseNotes.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 43ed754183be7..575a20288e685 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -86,8 +86,8 @@ Changes to the AMDGPU Backend
Changes to the ARM Backend
--------------------------
* The `+nosimd` attribute is now fully supported. Previously, this had no effect when being used with
-AArch32 targets, however will now disable NEON instructions being generated. The `simd` is also now
-printed when the `--print-supported-extensions` option is used..
+AArch32 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.
Changes to the AVR Backend
--------------------------
More information about the cfe-commits
mailing list