Skip to content

Commit 8da3a78

Browse files
committed
[ARM] Ensure FPU Selection can select mode correctly
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. For instances where a Single Precision FPU is used, SIMD will be disabled regardless of if `+nosimd` is passed as an option. This is because there is no Single Precision FPU that can support this feature.
1 parent 8baa0d9 commit 8da3a78

File tree

4 files changed

+55
-5
lines changed

4 files changed

+55
-5
lines changed

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,3 +1013,19 @@
10131013
// CHECK-MVE1_2: #define __ARM_FEATURE_MVE 1
10141014
// 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
10151015
// CHECK-MVE3: #define __ARM_FEATURE_MVE 3
1016+
1017+
// Cortex-R52 and Cortex-R52Plus correctly enable the `fpv5-sp-d16` FPU when compiling for the SP only version of the CPU.
1018+
// 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
1019+
// CHECK-R52: #define __ARM_FEATURE_FMA 1
1020+
// CHECK-R52: #define __ARM_FP 0x6
1021+
// CHECK-R52: #define __ARM_FPV5__ 1
1022+
// CHECK-R52: #define __ARM_VFPV2__ 1
1023+
// CHECK-R52-NEXT: #define __ARM_VFPV3__ 1
1024+
// CHECK-R52-NEXT: #define __ARM_VFPV4__ 1
1025+
// 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-R52PLUS %s
1026+
// CHECK-R52PLUS: #define __ARM_FEATURE_FMA 1
1027+
// CHECK-R52PLUS: #define __ARM_FP 0x6
1028+
// CHECK-R52PLUS: #define __ARM_FPV5__ 1
1029+
// CHECK-R52PLUS: #define __ARM_VFPV2__ 1
1030+
// CHECK-R52PLUS-NEXT: #define __ARM_VFPV3__ 1
1031+
// CHECK-R52PLUS-NEXT: #define __ARM_VFPV4__ 1

llvm/lib/TargetParser/ARMTargetParser.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -403,13 +403,12 @@ static ARM::FPUKind findSinglePrecisionFPU(ARM::FPUKind InputFPUKind) {
403403
if (!ARM::isDoublePrecision(InputFPU.Restriction))
404404
return InputFPUKind;
405405

406-
// Otherwise, look for an FPU entry with all the same fields, except
407-
// that it does not support double precision.
406+
// Otherwise, look for an FPU entry that has the same FPUVer
407+
// and is not Double Precision. We want to allow for changing of
408+
// NEON Support and Restrictions so CPU's such as Cortex-R52 can
409+
// select between SP Only and Full DP modes.
408410
for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) {
409411
if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
410-
CandidateFPU.NeonSupport == InputFPU.NeonSupport &&
411-
ARM::has32Regs(CandidateFPU.Restriction) ==
412-
ARM::has32Regs(InputFPU.Restriction) &&
413412
!ARM::isDoublePrecision(CandidateFPU.Restriction)) {
414413
return CandidateFPU.ID;
415414
}

llvm/test/MC/ARM/cortex-r52-nofp.s

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
@ RUN: llvm-mc -triple armv8-none-eabi -mcpu=cortex-r52 -mattr=+nosimd+nofp.dp %s -o - | FileCheck %s -check-prefix=CHECK-NO-FP
2+
@ RUN: llvm-mc -triple armv8-none-eabi -mcpu=cortex-r52 %s -o - | FileCheck %s -check-prefix=CHECK-FP
3+
4+
.text
5+
vadd.f32 s0, s1, s2
6+
@ CHECK-NO-FP: vadd.f32 s0, s1, s2
7+
@ CHECK-FP: vadd.f32 s0, s1, s2
8+
@ CHECK-NOT-NO-FP: error: instruction requires: VPF2
9+
@ CHECK-NOT-FP: error: instruction requires: VPF2

llvm/unittests/TargetParser/TargetParserTest.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "llvm/ADT/STLExtras.h"
1111
#include "llvm/ADT/StringExtras.h"
1212
#include "llvm/ADT/StringMap.h"
13+
#include "llvm/ADT/StringRef.h"
1314
#include "llvm/Support/ARMBuildAttributes.h"
1415
#include "llvm/Support/Debug.h"
1516
#include "llvm/Support/FormatVariadic.h"
@@ -2085,4 +2086,29 @@ INSTANTIATE_TEST_SUITE_P(
20852086
AArch64ExtensionDependenciesBaseCPUTestFixture,
20862087
::testing::ValuesIn(AArch64ExtensionDependenciesCPUData));
20872088

2089+
struct CheckFindSinglePrecisionFpuTest {
2090+
StringRef Cpu;
2091+
ARM::ArchKind Arch;
2092+
StringRef Archext;
2093+
std::vector<StringRef> Features;
2094+
ARM::FPUKind Fpu;
2095+
ARM::FPUKind Output;
2096+
};
2097+
2098+
TEST(TargetParserTest, checkFindSinglePrecisionFPU) {
2099+
CheckFindSinglePrecisionFpuTest tests[] = {
2100+
{"cortex-r4f", ARM::ArchKind::ARMV7R, "nofp.dp", {}, ARM::FK_INVALID, ARM::FK_VFPV3XD},
2101+
{"cortex-r7", ARM::ArchKind::ARMV7R, "nofp.dp", {}, ARM::FK_INVALID, ARM::FK_VFPV3XD_FP16},
2102+
{"cortex-a7", ARM::ArchKind::ARMV7A, "nofp.dp", {}, ARM::FK_INVALID, ARM::FK_FPV4_SP_D16},
2103+
{"cortex-r52", ARM::ArchKind::ARMV8R, "nofp.dp", {}, ARM::FK_INVALID, ARM::FK_FPV5_SP_D16},
2104+
{"cortex-m55", ARM::ArchKind::ARMV8_1MMainline, "nofp.dp", {}, ARM::FK_INVALID, ARM::FK_FP_ARMV8_FULLFP16_SP_D16}
2105+
};
2106+
2107+
for (auto X : tests) {
2108+
ARM::FPUKind FPU = X.Fpu;
2109+
EXPECT_TRUE(ARM::appendArchExtFeatures(X.Cpu, X.Arch, X.Archext, X.Features, FPU));
2110+
EXPECT_EQ(FPU, X.Output);
2111+
}
2112+
}
2113+
20882114
} // namespace

0 commit comments

Comments
 (0)