Skip to content

Commit d9af03b

Browse files
authored
[ARM] Ensure FPU Selection can select mode correctly (llvm#124935)
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.
1 parent c55a765 commit d9af03b

File tree

4 files changed

+78
-5
lines changed

4 files changed

+78
-5
lines changed

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,3 +1013,17 @@
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+
// 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
1020+
// 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
1021+
// 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
1022+
// CHECK-R52: #define __ARM_FEATURE_FMA 1
1023+
// CHECK-R52: #define __ARM_FP 0x6
1024+
// CHECK-R52: #define __ARM_FPV5__ 1
1025+
// CHECK-R52: #define __ARM_VFPV2__ 1
1026+
// CHECK-R52-NEXT: #define __ARM_VFPV3__ 1
1027+
// CHECK-R52-NEXT: #define __ARM_VFPV4__ 1
1028+
// CHECK-R52-NOT: #define __ARM_NEON 1
1029+
// CHECK-R52-NOT: #define __ARM_NEON__

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: 51 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,54 @@ 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",
2101+
ARM::ArchKind::ARMV7R,
2102+
"nofp.dp",
2103+
{},
2104+
ARM::FK_INVALID,
2105+
ARM::FK_VFPV3XD},
2106+
{"cortex-r7",
2107+
ARM::ArchKind::ARMV7R,
2108+
"nofp.dp",
2109+
{},
2110+
ARM::FK_INVALID,
2111+
ARM::FK_VFPV3XD_FP16},
2112+
{"cortex-a7",
2113+
ARM::ArchKind::ARMV7A,
2114+
"nofp.dp",
2115+
{},
2116+
ARM::FK_INVALID,
2117+
ARM::FK_FPV4_SP_D16},
2118+
{"cortex-r52",
2119+
ARM::ArchKind::ARMV8R,
2120+
"nofp.dp",
2121+
{},
2122+
ARM::FK_INVALID,
2123+
ARM::FK_FPV5_SP_D16},
2124+
{"cortex-m55",
2125+
ARM::ArchKind::ARMV8_1MMainline,
2126+
"nofp.dp",
2127+
{},
2128+
ARM::FK_INVALID,
2129+
ARM::FK_FP_ARMV8_FULLFP16_SP_D16}};
2130+
2131+
for (auto X : tests) {
2132+
ARM::FPUKind FPU = X.Fpu;
2133+
EXPECT_TRUE(
2134+
ARM::appendArchExtFeatures(X.Cpu, X.Arch, X.Archext, X.Features, FPU));
2135+
EXPECT_EQ(FPU, X.Output);
2136+
}
2137+
}
2138+
20882139
} // namespace

0 commit comments

Comments
 (0)