https://github.com/mstorsjo created 
https://github.com/llvm/llvm-project/pull/122095

Upstream LLVM implicitly enables NEON for any ARMv7 target.

Many platform ABIs with an ARMv7 baseline also include NEON in that, this is 
the case on e.g. Windows and iOS. On Linux, however, things are not quite as 
clearly defined. Some distributions target an ARMv7 baseline without NEON 
available (this is the case for e.g. Debian/Ubuntu for the "armhf" 
architecture).

To achieve this, Debian/Ubuntu patch LLVM downstream to make ARMv7 only 
implicitly enable VPFv3-D16, not NEON - see [1].

That patch has the (unintended) effect that NEON no longer is available by 
default for Windows/ARMv7 and iOS/ARMv7.

In practice, when compiling C for Windows/ARMv7, NEON actually still is 
available, but not when compiling assembly files. This is due to 
ARM::getARMCPUForArch (in
llvm/lib/TargetParser/ARMTargetParser.cpp) returning "cortex-a9" for Windows. 
This difference, between C and assembly, is due to how getARMTargetCPU is 
called in getARMTargetFeatures (in clang/lib/Driver/ToolChains/Arch/ARM.cpp) to 
get defaults, only when ForAS is not set - see [2].

There is an existing case in getARMTargetFeatures, for Android, which 
explicitly enables NEON when targeting ARM >= v7. As Windows and iOS have NEON 
as part of their ABI baseline just like Android does these days (see [3] for 
where this default was added for Android), add the implicit default in a 
similar way.

However, first do the general lookup of getARMTargetCPU (unless ForAS); this 
makes sure that we get the same default CPU as before ("cortex-a9" for Windows 
and "swift" for the "armv7s" architecture on Darwin).

[1] 
https://salsa.debian.org/pkg-llvm-team/llvm-toolchain/-/blob/19/debian/patches/clang-arm-default-vfp3-on-armv7a.patch?ref_type=heads
[2] 
https://github.com/llvm/llvm-project/commit/b8baa2a9132498ea286dbb0d03f005760ecc6fdb
[3] 
https://github.com/llvm/llvm-project/commit/d0fbef9c753a78aa20d5a462b682bfaf83cc6e6e

From 9c44a17017b0e99eecd3ed3606aa6b8acc0dbfd0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <mar...@martin.st>
Date: Fri, 4 Oct 2024 17:59:58 +0300
Subject: [PATCH] [clang] [ARM] Explicitly enable NEON for Windows/Darwin
 targets

Upstream LLVM implicitly enables NEON for any ARMv7 target.

Many platform ABIs with an ARMv7 baseline also include NEON in that,
this is the case on e.g. Windows and iOS. On Linux, however, things
are not quite as clearly defined. Some distributions target an ARMv7
baseline without NEON available (this is the case for e.g.
Debian/Ubuntu for the "armhf" architecture).

To achieve this, Debian/Ubuntu patch LLVM downstream to make
ARMv7 only implicitly enable VPFv3-D16, not NEON - see [1].

That patch has the (unintended) effect that NEON no longer is
available by default for Windows/ARMv7 and iOS/ARMv7.

In practice, when compiling C for Windows/ARMv7, NEON actually
still is available, but not when compiling assembly files.
This is due to ARM::getARMCPUForArch (in
llvm/lib/TargetParser/ARMTargetParser.cpp) returning "cortex-a9"
for Windows. This difference, between C and assembly, is due to
how getARMTargetCPU is called in getARMTargetFeatures (in
clang/lib/Driver/ToolChains/Arch/ARM.cpp) to get defaults, only
when ForAS is not set - see [2].

There is an existing case in getARMTargetFeatures, for Android,
which explicitly enables NEON when targeting ARM >= v7. As
Windows and iOS have NEON as part of their ABI baseline just like
Android does these days (see [3] for where this default was
added for Android), add the implicit default in a similar way.

However, first do the general lookup of getARMTargetCPU (unless
ForAS); this makes sure that we get the same default CPU
as before ("cortex-a9" for Windows and "swift" for the "armv7s"
architecture on Darwin).

[1] 
https://salsa.debian.org/pkg-llvm-team/llvm-toolchain/-/blob/19/debian/patches/clang-arm-default-vfp3-on-armv7a.patch?ref_type=heads
[2] 
https://github.com/llvm/llvm-project/commit/b8baa2a9132498ea286dbb0d03f005760ecc6fdb
[3] 
https://github.com/llvm/llvm-project/commit/d0fbef9c753a78aa20d5a462b682bfaf83cc6e6e
---
 clang/lib/Driver/ToolChains/Arch/ARM.cpp      |  8 ++++++
 clang/test/Driver/arm-mfpu.c                  |  6 +++--
 clang/test/Preprocessor/arm-target-features.c | 27 +++++++++++++++++++
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp 
b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
index b8181ce6dc012a..9e6fe4f60bb65d 100644
--- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -659,13 +659,21 @@ llvm::ARM::FPUKind arm::getARMTargetFeatures(const Driver 
&D,
         CPUArgFPUKind != llvm::ARM::FK_INVALID ? CPUArgFPUKind : 
ArchArgFPUKind;
     (void)llvm::ARM::getFPUFeatures(FPUKind, Features);
   } else {
+    bool Generic = true;
     if (!ForAS) {
       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()) &&
+        getARMSubArchVersionNumber(Triple) >= 7) {
+      FPUKind = llvm::ARM::parseFPU("neon");
+      (void)llvm::ARM::getFPUFeatures(FPUKind, Features);
+    }
   }
 
   // Now we've finished accumulating features from arch, cpu and fpu,
diff --git a/clang/test/Driver/arm-mfpu.c b/clang/test/Driver/arm-mfpu.c
index 1b174be388124d..669e7975675fa5 100644
--- a/clang/test/Driver/arm-mfpu.c
+++ b/clang/test/Driver/arm-mfpu.c
@@ -356,8 +356,10 @@
 // CHECK-HF-DAG: "-target-cpu" "arm1176jzf-s"
 
 // RUN: %clang -target armv7-apple-darwin -x assembler %s -### -c 2>&1 \
-// RUN:   | FileCheck --check-prefix=ASM %s
-// ASM-NOT: -target-feature
+// RUN:   | FileCheck --check-prefix=ASM-NEON %s
+// RUN: %clang -target armv7-windows -x assembler %s -### -c 2>&1 \
+// RUN:   | FileCheck --check-prefix=ASM-NEON %s
+// ASM-NEON: "-target-feature" "+neon"
 
 // RUN: %clang -target armv8-linux-gnueabi -mfloat-abi=soft -mfpu=none %s -### 
-c 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-SOFT-ABI-FP %s
diff --git a/clang/test/Preprocessor/arm-target-features.c 
b/clang/test/Preprocessor/arm-target-features.c
index 2999ee0d9e4d80..95ca7d0cbc3c2a 100644
--- a/clang/test/Preprocessor/arm-target-features.c
+++ b/clang/test/Preprocessor/arm-target-features.c
@@ -132,6 +132,30 @@
 // CHECK-V7VE-DEFAULT-ABI-SOFT: #define __ARM_ARCH_EXT_IDIV__ 1
 // CHECK-V7VE-DEFAULT-ABI-SOFT: #define __ARM_FP 0xc
 
+// RUN: %clang -target x86_64-apple-macosx10.10 -arch armv7 -x c -E -dM %s -o 
- | FileCheck -match-full-lines --check-prefix=CHECK-DARWIN-V7 %s
+// CHECK-DARWIN-V7: #define __ARMEL__ 1
+// CHECK-DARWIN-V7: #define __ARM_ARCH 7
+// CHECK-DARWIN-V7: #define __ARM_ARCH_7A__ 1
+// CHECK-DARWIN-V7-NOT: __ARM_FEATURE_CRC32
+// CHECK-DARWIN-V7-NOT: __ARM_FEATURE_NUMERIC_MAXMIN
+// CHECK-DARWIN-V7-NOT: __ARM_FEATURE_DIRECTED_ROUNDING
+// CHECK-DARWIN-V7: #define __ARM_FP 0xc
+// CHECK-DARWIN-V7: #define __ARM_NEON 1
+// CHECK-DARWIN-V7: #define __ARM_NEON_FP 0x4
+// CHECK-DARWIN-V7: #define __ARM_NEON__ 1
+
+// RUN: %clang -target armv7-windows -x c -E -dM %s -o - | FileCheck 
-match-full-lines --check-prefix=CHECK-WINDOWS-V7 %s
+// CHECK-WINDOWS-V7: #define __ARMEL__ 1
+// CHECK-WINDOWS-V7: #define __ARM_ARCH 7
+// CHECK-WINDOWS-V7: #define __ARM_ARCH_7A__ 1
+// CHECK-WINDOWS-V7-NOT: __ARM_FEATURE_CRC32
+// CHECK-WINDOWS-V7-NOT: __ARM_FEATURE_NUMERIC_MAXMIN
+// CHECK-WINDOWS-V7-NOT: __ARM_FEATURE_DIRECTED_ROUNDING
+// CHECK-WINDOWS-V7: #define __ARM_FP 0xe
+// CHECK-WINDOWS-V7: #define __ARM_NEON 1
+// CHECK-WINDOWS-V7: #define __ARM_NEON_FP 0x6
+// CHECK-WINDOWS-V7: #define __ARM_NEON__ 1
+
 // RUN: %clang -target x86_64-apple-macosx10.10 -arch armv7s -x c -E -dM %s -o 
- | FileCheck -match-full-lines --check-prefix=CHECK-V7S %s
 // CHECK-V7S: #define __ARMEL__ 1
 // CHECK-V7S: #define __ARM_ARCH 7
@@ -140,6 +164,9 @@
 // CHECK-V7S-NOT: __ARM_FEATURE_NUMERIC_MAXMIN
 // CHECK-V7S-NOT: __ARM_FEATURE_DIRECTED_ROUNDING
 // CHECK-V7S: #define __ARM_FP 0xe
+// CHECK-V7S: #define __ARM_NEON 1
+// CHECK-V7S: #define __ARM_NEON_FP 0x6
+// CHECK-V7S: #define __ARM_NEON__ 1
 
 // RUN: %clang -target arm-arm-none-eabi -march=armv7-m -mfloat-abi=soft -x c 
-E -dM %s | FileCheck -match-full-lines --check-prefix=CHECK-VFP-FP %s
 // RUN: %clang -target arm-arm-none-eabi -march=armv7-m -mfloat-abi=softfp -x 
c -E -dM %s | FileCheck -match-full-lines --check-prefix=CHECK-VFP-FP %s

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to