Author: Jack Styles
Date: 2025-04-15T09:00:14+01:00
New Revision: 06da00ae2d116bb2c4063b124429c2d29eb69d87

URL: 
https://github.com/llvm/llvm-project/commit/06da00ae2d116bb2c4063b124429c2d29eb69d87
DIFF: 
https://github.com/llvm/llvm-project/commit/06da00ae2d116bb2c4063b124429c2d29eb69d87.diff

LOG: [ARM][Clang] Make `+nosimd` functional for AArch32 Targets (#130623)

`+simd` and `+nosimd` are used to enable or disable NEON Instructions
when compiling for ARM 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.

To make this functional as intended, MVE and MVE.FP now rely on their
own Enum identifier, rather than `AEK_SIMD`. While SIMD does refer to
both Neon and Helium technologies, in terms of command line options,
SIMD relates to Neon. Helium relates to MVE and MVE.FP. The Enum
now reflects this too.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/test/CodeGen/arm-target-features.c
    clang/test/Driver/print-supported-extensions-arm.c
    clang/test/Preprocessor/arm-target-features.c
    llvm/include/llvm/TargetParser/ARMTargetParser.def
    llvm/include/llvm/TargetParser/ARMTargetParser.h
    llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp
    llvm/lib/TargetParser/ARMTargetParser.cpp
    llvm/unittests/TargetParser/TargetParserTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f7f198f15a4e0..ccd9f70aa875d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -525,6 +525,9 @@ X86 Support
 Arm and AArch64 Support
 ^^^^^^^^^^^^^^^^^^^^^^^
 - For ARM targets, cc1as now considers the FPU's features for the selected CPU 
or Architecture.
+- 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.
 
 Android Support
 ^^^^^^^^^^^^^^^

diff  --git a/clang/test/CodeGen/arm-target-features.c 
b/clang/test/CodeGen/arm-target-features.c
index ad4bfd45c408b..95ae27bd2db6c 100644
--- a/clang/test/CodeGen/arm-target-features.c
+++ b/clang/test/CodeGen/arm-target-features.c
@@ -119,4 +119,10 @@
 // RUN: %clang_cc1 -triple thumbv9.3a-linux-gnueabihf -emit-llvm -o - %s | 
FileCheck %s --check-prefix=CHECK-ARCH93
 // CHECK-ARCH93: 
"target-features"="+armv9.3-a,+thumb-mode,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8.7a,+v8.8a,+v9.1a,+v9.2a,+v9.3a,+v9a"
 
+// RUN: %clang_cc1 -triple arm-none-eabi -target-cpu cortex-r52 -emit-llvm -o 
- %s | FileCheck %s --check-prefix=CHECK-ARMSIMD-R52
+// CHECK-ARMSIMD-R52:  
"target-features"="+armv8-r,+crc,+d32,+dsp,+fp-armv8,+fp-armv8d16,+fp-armv8d16sp,+fp-armv8sp,+fp16,+fp64,+hwdiv,+hwdiv-arm,+neon,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,+vfp4,+vfp4d16,+vfp4d16sp,+vfp4sp,-thumb-mode"
+
+// RUN: %clang_cc1 -triple armv8-none-eabi -target-cpu cortex-a57 -emit-llvm 
-o - %s | FileCheck %s --check-prefix=CHECK-ARMSIMD-A57
+// CHECK-ARMSIMD-A57:  
"target-features"="+aes,+armv8-a,+crc,+d32,+dsp,+fp-armv8,+fp-armv8d16,+fp-armv8d16sp,+fp-armv8sp,+fp16,+fp64,+hwdiv,+hwdiv-arm,+neon,+sha2,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,+vfp4,+vfp4d16,+vfp4d16sp,+vfp4sp,-thumb-mode"
+
 void foo() {}

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..7b2a0ecdf9040 100644
--- a/clang/test/Preprocessor/arm-target-features.c
+++ b/clang/test/Preprocessor/arm-target-features.c
@@ -1027,3 +1027,19 @@
 // CHECK-R52-NEXT: #define __ARM_VFPV4__ 1
 // CHECK-R52-NOT: #define __ARM_NEON 1
 // CHECK-R52-NOT: #define __ARM_NEON__
+
+// Check that on AArch32, Neon is correctly activated when the target supports 
the feature
+// RUN:  %clang -target arm-none-eabi -march=armv8-a -mfloat-abi=hard -x c -E 
-dM -o - %s | FileCheck -check-prefix=CHECK-SIMD %s
+// RUN:  %clang -target arm-none-eabi -mcpu=cortex-r52 -mfloat-abi=hard -x c 
-E -dM -o - %s | FileCheck -check-prefix=CHECK-SIMD %s
+// RUN:  %clang -target arm-none-eabi -mcpu=cortex-a57 -mfloat-abi=hard -x c 
-E -dM -o - %s | FileCheck -check-prefix=CHECK-SIMD %s
+// CHECK-SIMD: #define __ARM_NEON 1
+// 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
+// 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/include/llvm/TargetParser/ARMTargetParser.def 
b/llvm/include/llvm/TargetParser/ARMTargetParser.def
index 6b96c3e83c8c4..ff53aa10b4481 100644
--- a/llvm/include/llvm/TargetParser/ARMTargetParser.def
+++ b/llvm/include/llvm/TargetParser/ARMTargetParser.def
@@ -224,12 +224,12 @@ 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, {}, {})
-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")
@@ -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 456c3b5396fc9..956fc9680ee33 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -12970,7 +12970,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/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 dcffc9471705f..b3c470b774de7 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,
@@ -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"));
 }


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to