Skip to content

Commit 3f02cd1

Browse files
Stylie777var-const
authored andcommitted
[ARM][Clang] Make +nosimd functional for AArch32 Targets (llvm#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.
1 parent 1a4cecc commit 3f02cd1

File tree

10 files changed

+43
-13
lines changed

10 files changed

+43
-13
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,9 @@ X86 Support
525525
Arm and AArch64 Support
526526
^^^^^^^^^^^^^^^^^^^^^^^
527527
- For ARM targets, cc1as now considers the FPU's features for the selected CPU or Architecture.
528+
- The ``+nosimd`` attribute is now fully supported for ARM. Previously, this had no effect when being used with
529+
ARM targets, however this will now disable NEON instructions being generated. The ``simd`` option is
530+
also now printed when the ``--print-supported-extensions`` option is used.
528531

529532
Android Support
530533
^^^^^^^^^^^^^^^

clang/test/CodeGen/arm-target-features.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,10 @@
119119
// RUN: %clang_cc1 -triple thumbv9.3a-linux-gnueabihf -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARCH93
120120
// 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"
121121

122+
// RUN: %clang_cc1 -triple arm-none-eabi -target-cpu cortex-r52 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARMSIMD-R52
123+
// 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"
124+
125+
// RUN: %clang_cc1 -triple armv8-none-eabi -target-cpu cortex-a57 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARMSIMD-A57
126+
// 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"
127+
122128
void foo() {}

clang/test/Driver/print-supported-extensions-arm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// CHECK-NEXT: dsp Supports DSP instructions in ARM and/or Thumb2
1313
// CHECK-NEXT: mve Support M-Class Vector Extension with integer ops
1414
// CHECK-NEXT: mve.fp Support M-Class Vector Extension with integer and floating ops
15+
// CHECK-NEXT: simd Enable NEON instructions
1516
// CHECK-NEXT: fp16 Enable half-precision floating point
1617
// CHECK-NEXT: ras Enable Reliability, Availability and Serviceability extensions
1718
// CHECK-NEXT: fp16fml Enable full half-precision floating point fml instructions

clang/test/Preprocessor/arm-target-features.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,3 +1027,19 @@
10271027
// CHECK-R52-NEXT: #define __ARM_VFPV4__ 1
10281028
// CHECK-R52-NOT: #define __ARM_NEON 1
10291029
// CHECK-R52-NOT: #define __ARM_NEON__
1030+
1031+
// Check that on AArch32, Neon is correctly activated when the target supports the feature
1032+
// RUN: %clang -target arm-none-eabi -march=armv8-a -mfloat-abi=hard -x c -E -dM -o - %s | FileCheck -check-prefix=CHECK-SIMD %s
1033+
// RUN: %clang -target arm-none-eabi -mcpu=cortex-r52 -mfloat-abi=hard -x c -E -dM -o - %s | FileCheck -check-prefix=CHECK-SIMD %s
1034+
// RUN: %clang -target arm-none-eabi -mcpu=cortex-a57 -mfloat-abi=hard -x c -E -dM -o - %s | FileCheck -check-prefix=CHECK-SIMD %s
1035+
// CHECK-SIMD: #define __ARM_NEON 1
1036+
// CHECK-SIMD: #define __ARM_NEON_FP 0x6
1037+
// CHECK-SIMD: #define __ARM_NEON__ 1
1038+
1039+
// Check that on AArch32 appropriate targets, +nosimd correctly disables NEON instructions.
1040+
// 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
1041+
// 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
1042+
// 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
1043+
// CHECK-NOSIMD-NOT: #define __ARM_NEON 1
1044+
// CHECK-NOSIMD-NOT: #define __ARM_NEON_FP 0x6
1045+
// CHECK-NOSIMD-NOT: #define __ARM_NEON__ 1

llvm/include/llvm/TargetParser/ARMTargetParser.def

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -224,12 +224,12 @@ ARM_ARCH_EXT_NAME("dotprod", ARM::AEK_DOTPROD, "+dotprod", "-dotprod")
224224
ARM_ARCH_EXT_NAME("dsp", ARM::AEK_DSP, "+dsp", "-dsp")
225225
ARM_ARCH_EXT_NAME("fp", ARM::AEK_FP, {}, {})
226226
ARM_ARCH_EXT_NAME("fp.dp", ARM::AEK_FP_DP, {}, {})
227-
ARM_ARCH_EXT_NAME("mve", (ARM::AEK_DSP | ARM::AEK_SIMD), "+mve", "-mve")
228-
ARM_ARCH_EXT_NAME("mve.fp", (ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP),
227+
ARM_ARCH_EXT_NAME("mve", (ARM::AEK_DSP | ARM::AEK_MVE), "+mve", "-mve")
228+
ARM_ARCH_EXT_NAME("mve.fp", (ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP),
229229
"+mve.fp", "-mve.fp")
230230
ARM_ARCH_EXT_NAME("idiv", (ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB), {}, {})
231231
ARM_ARCH_EXT_NAME("mp", ARM::AEK_MP, {}, {})
232-
ARM_ARCH_EXT_NAME("simd", ARM::AEK_SIMD, {}, {})
232+
ARM_ARCH_EXT_NAME("simd", ARM::AEK_SIMD, "+neon", "-neon")
233233
ARM_ARCH_EXT_NAME("sec", ARM::AEK_SEC, {}, {})
234234
ARM_ARCH_EXT_NAME("virt", ARM::AEK_VIRT, {}, {})
235235
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)
345345
ARM_CPU_NAME("star-mc1", ARMV8MMainline, FK_FPV5_SP_D16, false, ARM::AEK_DSP)
346346
ARM_CPU_NAME("cortex-m35p", ARMV8MMainline, FK_FPV5_SP_D16, false, ARM::AEK_DSP)
347347
ARM_CPU_NAME("cortex-m55", ARMV8_1MMainline, FK_FP_ARMV8_FULLFP16_D16, false,
348-
(ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP | ARM::AEK_FP16))
348+
(ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP | ARM::AEK_FP16))
349349
ARM_CPU_NAME("cortex-m85", ARMV8_1MMainline, FK_FP_ARMV8_FULLFP16_D16, false,
350-
(ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP | ARM::AEK_FP16 |
350+
(ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP | ARM::AEK_FP16 |
351351
ARM::AEK_RAS | ARM::AEK_PACBTI))
352352
ARM_CPU_NAME("cortex-m52", ARMV8_1MMainline, FK_FP_ARMV8_FULLFP16_D16, false,
353-
(ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP | ARM::AEK_FP16 |
353+
(ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP | ARM::AEK_FP16 |
354354
ARM::AEK_RAS | ARM::AEK_PACBTI))
355355
ARM_CPU_NAME("cortex-a32", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
356356
ARM_CPU_NAME("cortex-a35", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)

llvm/include/llvm/TargetParser/ARMTargetParser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ enum ArchExtKind : uint64_t {
6161
AEK_CDECP6 = 1 << 28,
6262
AEK_CDECP7 = 1 << 29,
6363
AEK_PACBTI = 1 << 30,
64+
AEK_MVE = 1ULL << 31,
6465
// Unsupported extensions.
6566
AEK_OS = 1ULL << 59,
6667
AEK_IWMMXT = 1ULL << 60,

llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12970,7 +12970,7 @@ bool ARMAsmParser::enableArchExtFeature(StringRef Name, SMLoc &ExtLoc) {
1297012970
{ARM::AEK_CRYPTO,
1297112971
{Feature_HasV8Bit},
1297212972
{ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12973-
{(ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP),
12973+
{(ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP),
1297412974
{Feature_HasV8_1MMainlineBit},
1297512975
{ARM::HasMVEFloatOps}},
1297612976
{ARM::AEK_FP,

llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ void ARMTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {
248248
emitFPU(STI.hasFeature(ARM::FeatureFP64) ? ARM::FK_FPV5_D16
249249
: ARM::FK_FPV5_SP_D16);
250250
if (STI.hasFeature(ARM::HasMVEFloatOps))
251-
emitArchExtension(ARM::AEK_SIMD | ARM::AEK_DSP | ARM::AEK_FP);
251+
emitArchExtension(ARM::AEK_MVE | ARM::AEK_DSP | ARM::AEK_FP);
252252
}
253253
} else if (STI.hasFeature(ARM::FeatureVFP4_D16_SP))
254254
emitFPU(STI.hasFeature(ARM::FeatureD32)

llvm/lib/TargetParser/ARMTargetParser.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,10 @@ void ARM::PrintSupportedExtensions(StringMap<StringRef> DescMap) {
657657
// Extensions without a feature cannot be used with -march.
658658
if (!Ext.Feature.empty()) {
659659
std::string Description = DescMap[Ext.Name].str();
660+
// With SIMD, this links to the NEON feature, so the description should be
661+
// taken from here, as SIMD does not exist in TableGen.
662+
if (Ext.Name == "simd")
663+
Description = DescMap["neon"].str();
660664
outs() << " "
661665
<< format(Description.empty() ? "%s\n" : "%-20s%s\n",
662666
Ext.Name.str().c_str(), Description.c_str());

llvm/unittests/TargetParser/TargetParserTest.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -507,17 +507,17 @@ INSTANTIATE_TEST_SUITE_P(
507507
"8-M.Mainline"),
508508
ARMCPUTestParams<uint64_t>(
509509
"cortex-m55", "armv8.1-m.main", "fp-armv8-fullfp16-d16",
510-
ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP |
510+
ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP |
511511
ARM::AEK_RAS | ARM::AEK_LOB | ARM::AEK_FP16,
512512
"8.1-M.Mainline"),
513513
ARMCPUTestParams<uint64_t>(
514514
"cortex-m85", "armv8.1-m.main", "fp-armv8-fullfp16-d16",
515-
ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP |
515+
ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP |
516516
ARM::AEK_RAS | ARM::AEK_LOB | ARM::AEK_FP16 | ARM::AEK_PACBTI,
517517
"8.1-M.Mainline"),
518518
ARMCPUTestParams<uint64_t>(
519519
"cortex-m52", "armv8.1-m.main", "fp-armv8-fullfp16-d16",
520-
ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP |
520+
ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP |
521521
ARM::AEK_RAS | ARM::AEK_LOB | ARM::AEK_FP16 | ARM::AEK_PACBTI,
522522
"8.1-M.Mainline"),
523523
ARMCPUTestParams<uint64_t>("iwmmxt", "iwmmxt", "none", ARM::AEK_NONE,
@@ -801,7 +801,7 @@ TEST(TargetParserTest, ARMArchExtFeature) {
801801
{"fp", "nofp", nullptr, nullptr},
802802
{"idiv", "noidiv", nullptr, nullptr},
803803
{"mp", "nomp", nullptr, nullptr},
804-
{"simd", "nosimd", nullptr, nullptr},
804+
{"simd", "nosimd", "+neon", "-neon"},
805805
{"sec", "nosec", nullptr, nullptr},
806806
{"virt", "novirt", nullptr, nullptr},
807807
{"fp16", "nofp16", "+fullfp16", "-fullfp16"},
@@ -1046,7 +1046,6 @@ TEST(TargetParserTest, ARMPrintSupportedExtensions) {
10461046
EXPECT_EQ(std::string::npos, captured.find("invalid"));
10471047
// Should not include anything that lacks a feature name. Checking a few here
10481048
// but not all as if one is hidden correctly the rest should be.
1049-
EXPECT_EQ(std::string::npos, captured.find("simd"));
10501049
EXPECT_EQ(std::string::npos, captured.find("maverick"));
10511050
EXPECT_EQ(std::string::npos, captured.find("xscale"));
10521051
}

0 commit comments

Comments
 (0)