diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index fd9b9a80e9938..63ec97a61ba43 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -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 ^^^^^^^^^^^^^^^ 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 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( "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( "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( "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("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")); }