Skip to content

[ARM][Clang] Make +nosimd functional for AArch32 Targets #130623

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Apr 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,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
^^^^^^^^^^^^^^^
Expand Down
6 changes: 6 additions & 0 deletions clang/test/CodeGen/arm-target-features.c
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
1 change: 1 addition & 0 deletions clang/test/Driver/print-supported-extensions-arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions clang/test/Preprocessor/arm-target-features.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
12 changes: 6 additions & 6 deletions llvm/include/llvm/TargetParser/ARMTargetParser.def
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/TargetParser/ARMTargetParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/TargetParser/ARMTargetParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
9 changes: 4 additions & 5 deletions llvm/unittests/TargetParser/TargetParserTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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"},
Expand Down Expand Up @@ -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"));
}
Expand Down
Loading