Skip to content

Commit

Permalink
[ARM] Ensure FPU Selection can select mode correctly (llvm#124935)
Browse files Browse the repository at this point in the history
Previously, when selecting a Single Precision FPU, LLVM would ensure all
elements of the Candidate FPU matched the InputFPU that was given.
However, for cases such as Cortex-R52, there are FPU options where not
all fields match exactly, for example NEON Support or Restrictions on
the Registers available.

This change ensures that LLVM can select the FPU correctly, removing the
requirement for Neon Support and Restrictions for the Candidate FPU to
be the same as the InputFPU.
  • Loading branch information
Stylie777 authored Feb 4, 2025
1 parent c55a765 commit d9af03b
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 5 deletions.
14 changes: 14 additions & 0 deletions clang/test/Preprocessor/arm-target-features.c
Original file line number Diff line number Diff line change
Expand Up @@ -1013,3 +1013,17 @@
// CHECK-MVE1_2: #define __ARM_FEATURE_MVE 1
// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+mve.fp -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-MVE3 %s
// CHECK-MVE3: #define __ARM_FEATURE_MVE 3

// Cortex-R52 and Cortex-R52Plus correctly enable the `fpv5-sp-d16` FPU when compiling for the SP only version of the CPU.
// RUN: %clang -target arm-none-eabi -mcpu=cortex-r52+nosimd+nofp.dp -mfloat-abi=hard -x c -E -dM -o - %s | FileCheck -check-prefix=CHECK-R52 %s
// RUN: %clang -target arm-none-eabi -mcpu=cortex-r52plus+nosimd+nofp.dp -mfloat-abi=hard -x c -E -dM -o - %s | FileCheck -check-prefix=CHECK-R52 %s
// RUN: %clang -target arm-none-eabi -mcpu=cortex-r52+nofp.dp -mfloat-abi=hard -x c -E -dM -o - %s | FileCheck -check-prefix=CHECK-R52 %s
// RUN: %clang -target arm-none-eabi -mcpu=cortex-r52plus+nofp.dp -mfloat-abi=hard -x c -E -dM -o - %s | FileCheck -check-prefix=CHECK-R52 %s
// CHECK-R52: #define __ARM_FEATURE_FMA 1
// CHECK-R52: #define __ARM_FP 0x6
// CHECK-R52: #define __ARM_FPV5__ 1
// CHECK-R52: #define __ARM_VFPV2__ 1
// CHECK-R52-NEXT: #define __ARM_VFPV3__ 1
// CHECK-R52-NEXT: #define __ARM_VFPV4__ 1
// CHECK-R52-NOT: #define __ARM_NEON 1
// CHECK-R52-NOT: #define __ARM_NEON__
9 changes: 4 additions & 5 deletions llvm/lib/TargetParser/ARMTargetParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,13 +403,12 @@ static ARM::FPUKind findSinglePrecisionFPU(ARM::FPUKind InputFPUKind) {
if (!ARM::isDoublePrecision(InputFPU.Restriction))
return InputFPUKind;

// Otherwise, look for an FPU entry with all the same fields, except
// that it does not support double precision.
// Otherwise, look for an FPU entry that has the same FPUVer
// and is not Double Precision. We want to allow for changing of
// NEON Support and Restrictions so CPU's such as Cortex-R52 can
// select between SP Only and Full DP modes.
for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) {
if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
CandidateFPU.NeonSupport == InputFPU.NeonSupport &&
ARM::has32Regs(CandidateFPU.Restriction) ==
ARM::has32Regs(InputFPU.Restriction) &&
!ARM::isDoublePrecision(CandidateFPU.Restriction)) {
return CandidateFPU.ID;
}
Expand Down
9 changes: 9 additions & 0 deletions llvm/test/MC/ARM/cortex-r52-nofp.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@ RUN: llvm-mc -triple armv8-none-eabi -mcpu=cortex-r52 -mattr=+nosimd+nofp.dp %s -o - | FileCheck %s -check-prefix=CHECK-NO-FP
@ RUN: llvm-mc -triple armv8-none-eabi -mcpu=cortex-r52 %s -o - | FileCheck %s -check-prefix=CHECK-FP

.text
vadd.f32 s0, s1, s2
@ CHECK-NO-FP: vadd.f32 s0, s1, s2
@ CHECK-FP: vadd.f32 s0, s1, s2
@ CHECK-NOT-NO-FP: error: instruction requires: VPF2
@ CHECK-NOT-FP: error: instruction requires: VPF2
51 changes: 51 additions & 0 deletions llvm/unittests/TargetParser/TargetParserTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FormatVariadic.h"
Expand Down Expand Up @@ -2085,4 +2086,54 @@ INSTANTIATE_TEST_SUITE_P(
AArch64ExtensionDependenciesBaseCPUTestFixture,
::testing::ValuesIn(AArch64ExtensionDependenciesCPUData));

struct CheckFindSinglePrecisionFpuTest {
StringRef Cpu;
ARM::ArchKind Arch;
StringRef Archext;
std::vector<StringRef> Features;
ARM::FPUKind Fpu;
ARM::FPUKind Output;
};

TEST(TargetParserTest, checkFindSinglePrecisionFPU) {
CheckFindSinglePrecisionFpuTest tests[] = {
{"cortex-r4f",
ARM::ArchKind::ARMV7R,
"nofp.dp",
{},
ARM::FK_INVALID,
ARM::FK_VFPV3XD},
{"cortex-r7",
ARM::ArchKind::ARMV7R,
"nofp.dp",
{},
ARM::FK_INVALID,
ARM::FK_VFPV3XD_FP16},
{"cortex-a7",
ARM::ArchKind::ARMV7A,
"nofp.dp",
{},
ARM::FK_INVALID,
ARM::FK_FPV4_SP_D16},
{"cortex-r52",
ARM::ArchKind::ARMV8R,
"nofp.dp",
{},
ARM::FK_INVALID,
ARM::FK_FPV5_SP_D16},
{"cortex-m55",
ARM::ArchKind::ARMV8_1MMainline,
"nofp.dp",
{},
ARM::FK_INVALID,
ARM::FK_FP_ARMV8_FULLFP16_SP_D16}};

for (auto X : tests) {
ARM::FPUKind FPU = X.Fpu;
EXPECT_TRUE(
ARM::appendArchExtFeatures(X.Cpu, X.Arch, X.Archext, X.Features, FPU));
EXPECT_EQ(FPU, X.Output);
}
}

} // namespace

0 comments on commit d9af03b

Please sign in to comment.