aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Kirth <paulkirth@google.com>2024-02-22 14:26:11 -0800
committerGitHub <noreply@github.com>2024-02-22 14:26:11 -0800
commite314622f204a01ffeda59cbe046dd403b01f8b74 (patch)
tree573c040c78d18ca09bcfc110d41389575cb848f5
parente2f08268304dc972440391c43bf1d47e28fad93e (diff)
downloadllvm-e314622f204a01ffeda59cbe046dd403b01f8b74.zip
llvm-e314622f204a01ffeda59cbe046dd403b01f8b74.tar.gz
llvm-e314622f204a01ffeda59cbe046dd403b01f8b74.tar.bz2
[clang][driver] Allow unaligned access on ARMv7 and higher by default (#82400)
ARM's Clang and GCC embedded compilers default to allowing unaligned access for ARMv7+. This patch changes the Clang driver default to match. Users can opt out with `-mno-unaligned-access`. Fixes #59560
-rw-r--r--clang/docs/ReleaseNotes.rst11
-rw-r--r--clang/lib/Driver/ToolChains/Arch/ARM.cpp24
-rw-r--r--clang/test/Driver/arm-alignment.c15
3 files changed, 38 insertions, 12 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 74bb9a0..19cc5b7 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -302,6 +302,17 @@ X86 Support
Arm and AArch64 Support
^^^^^^^^^^^^^^^^^^^^^^^
+- ARMv7+ targets now default to allowing unaligned access, except Armv6-M, and
+ Armv8-M without the Main Extension. Baremetal targets should check that the
+ new default will work with their system configurations, since it requires
+ that SCTLR.A is 0, SCTLR.U is 1, and that the memory in question is
+ configured as "normal" memory. This brings Clang in-line with the default
+ settings for GCC and Arm Compiler. Aside from making Clang align with other
+ compilers, changing the default brings major performance and code size
+ improvements for most targets. We have not changed the default behavior for
+ ARMv6, but may revisit that decision in the future. Users can restore the old
+ behavior with -m[no-]unaligned-access.
+
Android Support
^^^^^^^^^^^^^^^
diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
index e6ee2f8..ba158b9 100644
--- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -890,25 +890,25 @@ fp16_fml_fallthrough:
// SCTLR.U bit, which is architecture-specific. We assume ARMv6
// Darwin and NetBSD targets support unaligned accesses, and others don't.
//
- // ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit
- // which raises an alignment fault on unaligned accesses. Linux
- // defaults this bit to 0 and handles it as a system-wide (not
- // per-process) setting. It is therefore safe to assume that ARMv7+
- // Linux targets support unaligned accesses. The same goes for NaCl
- // and Windows.
+ // ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit which
+ // raises an alignment fault on unaligned accesses. Assume ARMv7+ supports
+ // unaligned accesses, except ARMv6-M, and ARMv8-M without the Main
+ // Extension. This aligns with the default behavior of ARM's downstream
+ // versions of GCC and Clang.
//
- // The above behavior is consistent with GCC.
+ // Users can change the default behavior via -m[no-]unaliged-access.
int VersionNum = getARMSubArchVersionNumber(Triple);
if (Triple.isOSDarwin() || Triple.isOSNetBSD()) {
if (VersionNum < 6 ||
Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
Features.push_back("+strict-align");
- } else if (Triple.isOSLinux() || Triple.isOSNaCl() ||
- Triple.isOSWindows()) {
- if (VersionNum < 7)
- Features.push_back("+strict-align");
- } else
+ } else if (VersionNum < 7 ||
+ Triple.getSubArch() ==
+ llvm::Triple::SubArchType::ARMSubArch_v6m ||
+ Triple.getSubArch() ==
+ llvm::Triple::SubArchType::ARMSubArch_v8m_baseline) {
Features.push_back("+strict-align");
+ }
}
// llvm does not support reserving registers in general. There is support
diff --git a/clang/test/Driver/arm-alignment.c b/clang/test/Driver/arm-alignment.c
index 9177b62..8c915477 100644
--- a/clang/test/Driver/arm-alignment.c
+++ b/clang/test/Driver/arm-alignment.c
@@ -22,6 +22,21 @@
// RUN: %clang -target armv7-windows -### %s 2> %t
// RUN: FileCheck --check-prefix=CHECK-UNALIGNED-ARM < %t %s
+// RUN: %clang --target=armv6 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-ALIGNED-ARM < %t %s
+
+// RUN: %clang --target=armv7 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-UNALIGNED-ARM < %t %s
+
+// RUN: %clang -target thumbv6m-none-gnueabi -mcpu=cortex-m0 -### %s 2> %t
+// RUN: FileCheck --check-prefix CHECK-ALIGNED-ARM <%t %s
+
+// RUN: %clang -target thumb-none-gnueabi -mcpu=cortex-m0 -### %s 2> %t
+// RUN: FileCheck --check-prefix CHECK-ALIGNED-ARM <%t %s
+
+// RUN: %clang -target thumbv8m.base-none-gnueabi -### %s 2> %t
+// RUN: FileCheck --check-prefix CHECK-ALIGNED-ARM <%t %s
+
// RUN: %clang --target=aarch64 -munaligned-access -### %s 2> %t
// RUN: FileCheck --check-prefix=CHECK-UNALIGNED-AARCH64 < %t %s