[Clang][ARM] Ensure FPU Features are parsed when targeting cc1as (#134612)

Previously, `cc1as` did not consider the Features that can be included
from a target's FPU. This could lead to a situation where assembly files
could not compile as cc1as did not know if a feature was supported.

With this change, all the features for the FPU will be passed to `cc1as`
as `-target-feature` lines. By making this change, it will enable
`+nosimd` to be functional, worked on in #130623, and fix a regression
introduced in 8fa0f0efce5fb81eb422e6d7eec74c66dafef4a3 so
armv7s-apple-darwin targets can utilise VFPv4 correctly.

---------

Co-authored-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
Jack Styles 2025-04-14 08:15:42 +01:00 committed by GitHub
parent cf188d650c
commit 53cd5cfc67
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 111 additions and 27 deletions

View File

@ -38,6 +38,9 @@ Potentially Breaking Changes
- Fix missing diagnostics for uses of declarations when performing typename access, - Fix missing diagnostics for uses of declarations when performing typename access,
such as when performing member access on a '[[deprecated]]' type alias. such as when performing member access on a '[[deprecated]]' type alias.
(#GH58547) (#GH58547)
- For ARM targets when compiling assembly files, the features included in the selected CPU
or Architecture's FPU are included. If you wish not to use a specific feature,
the relevant ``+no`` option will need to be amended to the command line option.
C/C++ Language Potentially Breaking Changes C/C++ Language Potentially Breaking Changes
------------------------------------------- -------------------------------------------
@ -512,6 +515,7 @@ X86 Support
Arm and AArch64 Support Arm and AArch64 Support
^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
- For ARM targets, cc1as now considers the FPU's features for the selected CPU or Architecture.
Android Support Android Support
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^

View File

@ -679,21 +679,17 @@ llvm::ARM::FPUKind arm::getARMTargetFeatures(const Driver &D,
CPUArgFPUKind != llvm::ARM::FK_INVALID ? CPUArgFPUKind : ArchArgFPUKind; CPUArgFPUKind != llvm::ARM::FK_INVALID ? CPUArgFPUKind : ArchArgFPUKind;
(void)llvm::ARM::getFPUFeatures(FPUKind, Features); (void)llvm::ARM::getFPUFeatures(FPUKind, Features);
} else { } else {
bool Generic = true; std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple);
if (!ForAS) { bool Generic = CPU == "generic";
std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple);
if (CPU != "generic")
Generic = false;
llvm::ARM::ArchKind ArchKind =
arm::getLLVMArchKindForARM(CPU, ArchName, Triple);
FPUKind = llvm::ARM::getDefaultFPU(CPU, ArchKind);
(void)llvm::ARM::getFPUFeatures(FPUKind, Features);
}
if (Generic && (Triple.isOSWindows() || Triple.isOSDarwin()) && if (Generic && (Triple.isOSWindows() || Triple.isOSDarwin()) &&
getARMSubArchVersionNumber(Triple) >= 7) { getARMSubArchVersionNumber(Triple) >= 7) {
FPUKind = llvm::ARM::parseFPU("neon"); FPUKind = llvm::ARM::parseFPU("neon");
(void)llvm::ARM::getFPUFeatures(FPUKind, Features); } else {
llvm::ARM::ArchKind ArchKind =
arm::getLLVMArchKindForARM(CPU, ArchName, Triple);
FPUKind = llvm::ARM::getDefaultFPU(CPU, ArchKind);
} }
(void)llvm::ARM::getFPUFeatures(FPUKind, Features);
} }
// Now we've finished accumulating features from arch, cpu and fpu, // Now we've finished accumulating features from arch, cpu and fpu,

View File

@ -0,0 +1,36 @@
// REQUIRES: arm-registered-target
/// Ensures that when targeting an ARM target with an Asm file, clang
/// collects the features from the FPU. This is critical in the
/// activation of NEON for supported targets. The Cortex-R52 will be
/// used and tested for VFP and NEON Support
// RUN: %clang -target arm-none-eabi -mcpu=cortex-r52 -c %s -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-STDERR %s --allow-empty
// RUN: %clang -target arm-none-eabi -mcpu=cortex-r52 -c %s -o /dev/null -### 2>&1 | FileCheck --check-prefix=CHECK-TARGET-FEATURES %s
/// Check that no errors or warnings are present when assembling using cc1as.
// CHECK-STDERR-NOT: error:
// CHECK-STDERR-NOT: warning:
/// Check that NEON and VFPV5 have been activated when using Cortex-R52 when using cc1as
// CHECK-TARGET-FEATURES: "-target-feature" "+vfp2sp"
// CHECK-TARGET-FEATURES: "-target-feature" "+vfp3"
// CHECK-TARGET-FEATURES: "-target-feature" "+fp-armv8"
// CHECK-TARGET-FEATURES: "-target-feature" "+fp-armv8d16"
// CHECK-TARGET-FEATURES: "-target-feature" "+fp-armv8d16sp"
// CHECK-TARGET-FEATURES: "-target-feature" "+fp-armv8sp"
// CHECK-TARGET-FEATURES: "-target-feature" "+neon"
vadd.f32 s0, s1, s2
vadd.f64 d0, d1, d2
vcvt.u32.f32 s0, s0, #1
vcvt.u32.f64 d0, d0, #1
vcvtb.f32.f16 s0, s1
vcvtb.f64.f16 d0, s1
vfma.f32 s0, s1, s2
vfma.f64 d0, d1, d2
vcvta.u32.f32 s0, s1
vcvta.u32.f64 s0, d1
vadd.f32 q0, q1, q2
vcvt.f32.f16 q0, d1
vfma.f32 q0, q1, q2
vcvta.u32.f32 q0, q1

View File

@ -0,0 +1,16 @@
/// Ensure that we can assemble NEON by just specifying an armv7
/// Apple or Windows target.
// REQUIRES: arm-registered-target
// RUN: %clang -c -target armv7-apple-darwin -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-STDERR %s --allow-empty
// RUN: %clang -c -target armv7-apple-darwin -o /dev/null %s -### 2>&1 | FileCheck --check-prefix=CHECK-TARGET-FEATURES %s
// RUN: %clang -c -target armv7-windows -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-STDERR %s --allow-empty
// RUN: %clang -c -target armv7-windows -o /dev/null %s -### 2>&1 | FileCheck --check-prefix=CHECK-TARGET-FEATURES %s
/// Check that no errors or warnings are present when assembling using cc1as.
// CHECK-STDERR-NOT: error:
// CHECK-STDERR-NOT: warning:
// CHECK-TARGET-FEATURES: "-target-feature" "+neon"
vadd.i32 q0, q0, q0

View File

@ -0,0 +1,13 @@
/// Ensure that we can assemble VFPv4 by just specifying an armv7s target.
// REQUIRES: arm-registered-target
// RUN: %clang -c -target armv7s-apple-darwin -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-STDERR %s --allow-empty
// RUN: %clang -c -target armv7s-apple-darwin -o /dev/null %s -### 2>&1 | FileCheck --check-prefix=CHECK-TARGET-FEATURES %s
/// Check that no errors or warnings are present when assembling using cc1as.
// CHECK-STDERR-NOT: error:
// CHECK-STDERR-NOT: warning:
// CHECK-TARGET-FEATURES: "-target-feature" "+vfp4"
vfma.f32 q1, q2, q3

View File

@ -8,21 +8,21 @@
# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+fp -o /dev/null %s 2>%t # RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+fp -o /dev/null %s 2>%t
# RUN: FileCheck --check-prefix=ERROR-V81M_FP < %t %s # RUN: FileCheck --check-prefix=ERROR-V81M_FP < %t %s
# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+nofp -o /dev/null %s 2>%t # RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+nofp -o /dev/null %s 2>%t
# RUN: FileCheck --check-prefix=ERROR-V81M_FP < %t %s # RUN: FileCheck --check-prefix=ERROR-V81M_NOFP < %t %s
# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+fp.dp -o /dev/null %s 2>%t # RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+fp.dp -o /dev/null %s 2>%t
# RUN: FileCheck --check-prefix=ERROR-V81M_FPDP < %t %s # RUN: FileCheck --check-prefix=ERROR-V81M_FPDP < %t %s
# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+nofp.dp -o /dev/null %s 2>%t # RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+nofp.dp -o /dev/null %s 2>%t
# RUN: FileCheck --check-prefix=ERROR-V81M_FPDP < %t %s # RUN: FileCheck --check-prefix=ERROR-V81M_NOFPDP < %t %s
# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+mve -o /dev/null %s 2>%t # RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+mve -o /dev/null %s 2>%t
# RUN: FileCheck --check-prefix=ERROR-V81M_MVE < %t %s # RUN: FileCheck --check-prefix=ERROR-V81M_MVE < %t %s
# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+nomve -o /dev/null %s 2>%t # RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+nomve -o /dev/null %s 2>%t
# RUN: FileCheck --check-prefix=ERROR-V81M_MVE < %t %s # RUN: FileCheck --check-prefix=ERROR-V81M_NOMVE < %t %s
# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+mve+fp -o /dev/null %s 2>%t # RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+mve+fp -o /dev/null %s 2>%t
# RUN: FileCheck --check-prefix=ERROR-V81M_MVE_FP < %t %s # RUN: FileCheck --check-prefix=ERROR-V81M_MVE_FP < %t %s
# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+mve.fp -o /dev/null %s 2>%t # RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+mve.fp -o /dev/null %s 2>%t
# RUN: FileCheck --check-prefix=ERROR-V81M_MVEFP < %t %s # RUN: FileCheck --check-prefix=ERROR-V81M_MVEFP < %t %s
# RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+nomve.fp -o /dev/null %s 2>%t # RUN: not %clang -c -target arm-none-none-eabi -march=armv8.1-m.main+nomve.fp -o /dev/null %s 2>%t
# RUN: FileCheck --check-prefix=ERROR-V81M_MVEFP < %t %s # RUN: FileCheck --check-prefix=ERROR-V81M_NOMVEFP < %t %s
.syntax unified .syntax unified
.thumb .thumb
@ -35,28 +35,41 @@ qadd r0, r1, r2
# ERROR-V8M: :[[@LINE-1]]:1: error # ERROR-V8M: :[[@LINE-1]]:1: error
# ERROR-V81M: :[[@LINE-2]]:1: error # ERROR-V81M: :[[@LINE-2]]:1: error
# ERROR-V81M_FP: :[[@LINE-3]]:1: error # ERROR-V81M_FP: :[[@LINE-3]]:1: error
# ERROR-V81M_FPDP: :[[@LINE-4]]:1: error # ERROR-V81M_NOFP: :[[@LINE-4]]:1: error
# ERROR-V81M_FPDP: :[[@LINE-5]]:1: error
# ERROR-V81M_NOFPDP: :[[@LINE-6]]:1: error
# ERROR-V81M_NOMVE: :[[@LINE-7]]:1: error
# ERROR-V81M_NOMVEFP: :[[@LINE-8]]:1: error
vadd.f16 s0, s1, s2 vadd.f16 s0, s1, s2
# ERROR-V8M: :[[@LINE-1]]:1: error # ERROR-V8M: :[[@LINE-1]]:1: error
# ERROR-V81M: :[[@LINE-2]]:1: error # ERROR-V81M_NOFP: :[[@LINE-2]]:1: error
# ERROR-V81M_DSP: :[[@LINE-3]]:1: error
# ERROR-V81M_MVE: :[[@LINE-4]]:1: error
vabs.f32 s0, s1 vabs.f32 s0, s1
# ERROR-V8M: :[[@LINE-1]]:1: error # ERROR-V81M_NOFP: :[[@LINE-1]]:1: error
# ERROR-V81M: :[[@LINE-2]]:1: error
# ERROR-V81M_DSP: :[[@LINE-3]]:1: error
# ERROR-V81M_MVE: :[[@LINE-4]]:1: error
vcmp.f64 d0,d1 vabs.s32 q0, q1
# ERROR-V8M: :[[@LINE-1]]:1: error # ERROR-V8M: :[[@LINE-1]]:1: error
# ERROR-V81M: :[[@LINE-2]]:1: error # ERROR-V81M: :[[@LINE-2]]:1: error
# ERROR-V81M_DSP: :[[@LINE-3]]:1: error # ERROR-V81M_DSP: :[[@LINE-3]]:1: error
# ERROR-V81M_FP: :[[@LINE-4]]:1: error # ERROR-V81M_FP: :[[@LINE-4]]:1: error
# ERROR-V81M_MVE: :[[@LINE-5]]:1: error # ERROR-V81M_NOFP: :[[@LINE-5]]:1: error
# ERROR-V81M_MVE_FP: :[[@LINE-6]]:1: error # ERROR-V81M_FPDP: :[[@LINE-6]]:1: error
# ERROR-V81M_MVEFP: :[[@LINE-7]]:1: error # ERROR-V81M_NOFPDP: :[[@LINE-7]]:1: error
# ERROR-V81M_NOMVE: :[[@LINE-8]]:1: error
# ERROR-V81M_NOMVEFP: :[[@LINE-9]]:1: error
vcmp.f64 d0,d1
# ERROR-V81M: :[[@LINE-1]]:1: error
# ERROR-V81M_DSP: :[[@LINE-2]]:1: error
# ERROR-V81M_FP: :[[@LINE-3]]:1: error
# ERROR-V81M_NOFP: :[[@LINE-4]]:1: error
# ERROR-V81M_NOFPDP: :[[@LINE-5]]:1: error
# ERROR-V81M_MVE: :[[@LINE-6]]:1: error
# ERROR-V81M_NOMVE: :[[@LINE-7]]:1: error
# ERROR-V81M_MVE_FP: :[[@LINE-8]]:1: error
# ERROR-V81M_MVEFP: :[[@LINE-9]]:1: error
# ERROR-V81M_NOMVEFP: :[[@LINE-10]]:1: error
asrl r0, r1, r2 asrl r0, r1, r2
# ERROR-V8M: :[[@LINE-1]]:1: error # ERROR-V8M: :[[@LINE-1]]:1: error
@ -64,6 +77,9 @@ asrl r0, r1, r2
# ERROR-V81M_DSP: :[[@LINE-3]]:1: error # ERROR-V81M_DSP: :[[@LINE-3]]:1: error
# ERROR-V81M_FP: :[[@LINE-4]]:1: error # ERROR-V81M_FP: :[[@LINE-4]]:1: error
# ERROR-V81M_FPDP: :[[@LINE-5]]:1: error # ERROR-V81M_FPDP: :[[@LINE-5]]:1: error
# ERROR-V81M_NOFPDP: :[[@LINE-6]]:1: error
# ERROR-V81M_NOMVE: :[[@LINE-7]]:1: error
# ERROR-V81M_NOMVEFP: :[[@LINE-8]]:1: error
vcadd.i8 q0, q1, q2, #90 vcadd.i8 q0, q1, q2, #90
# ERROR-V8M: :[[@LINE-1]]:1: error # ERROR-V8M: :[[@LINE-1]]:1: error
@ -71,3 +87,6 @@ vcadd.i8 q0, q1, q2, #90
# ERROR-V81M_DSP: :[[@LINE-3]]:1: error # ERROR-V81M_DSP: :[[@LINE-3]]:1: error
# ERROR-V81M_FP: :[[@LINE-4]]:1: error # ERROR-V81M_FP: :[[@LINE-4]]:1: error
# ERROR-V81M_FPDP: :[[@LINE-5]]:1: error # ERROR-V81M_FPDP: :[[@LINE-5]]:1: error
# ERROR-V81M_NOFPDP: :[[@LINE-6]]:1: error
# ERROR-V81M_NOMVE: :[[@LINE-7]]:1: error
# ERROR-V81M_NOMVEFP: :[[@LINE-8]]:1: error