diff options
author | Paul Kirth <paulkirth@google.com> | 2024-02-22 14:26:11 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-22 14:26:11 -0800 |
commit | e314622f204a01ffeda59cbe046dd403b01f8b74 (patch) | |
tree | 573c040c78d18ca09bcfc110d41389575cb848f5 | |
parent | e2f08268304dc972440391c43bf1d47e28fad93e (diff) | |
download | llvm-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.rst | 11 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Arch/ARM.cpp | 24 | ||||
-rw-r--r-- | clang/test/Driver/arm-alignment.c | 15 |
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 |