[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.
This commit is contained in:
@@ -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
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user