From 2f81ac852bc5aafc91c8e2adc66b5114761703c4 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Sat, 23 Sep 2023 23:28:48 +0300 Subject: [PATCH] Build: Enabled unaligned access by default on PowerPC64LE and some RISC-V. PowerPC64LE wasn't tested but it seems like a safe change. POWER8 supports unaligned access in little endian mode. Testing on godbolt.org shows that GCC uses unaligned access by default. The RISC-V macro __riscv_misaligned_fast is very new and not in any stable compiler release yet. Documentation in INSTALL was updated to match. Documentation about an autodetection bug when using ARM64 GCC with -mstrict-align was added to INSTALL. CMake files weren't updated yet. --- INSTALL | 39 +++++++++++++++++++++++++++++++++++++-- m4/tuklib_integer.m4 | 34 +++++++++++++++++++++++++++------- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/INSTALL b/INSTALL index c9b1d7ac..c83e3f3b 100644 --- a/INSTALL +++ b/INSTALL @@ -400,8 +400,43 @@ XZ Utils Installation slow. This option shouldn't be used on systems that rely on such emulation. - Unaligned access is enabled by default on x86, x86-64, - big endian PowerPC, some ARM, and some ARM64 systems. + Unaligned access is enabled by default on these: + - 32-bit x86 + - 64-bit x86-64 + - 32-bit big endian PowerPC + - 64-bit big endian PowerPC + - 64-bit little endian PowerPC + - some RISC-V [1] + - some 32-bit ARM [2] + - some 64-bit ARM64 [2] (NOTE: Autodetection bug + if using GCC -mstrict-align, see below.) + + [1] Unaligned access is enabled by default if + configure sees that the C compiler + #defines __riscv_misaligned_fast. + + [2] Unaligned access is enabled by default if + configure sees that the C compiler + #defines __ARM_FEATURE_UNALIGNED: + + - ARMv7 + GCC or Clang: It works. The options + -munaligned-access and -mno-unaligned-access + affect this macro correctly. + + - ARM64 + Clang: It works. The options + -munaligned-access, -mno-unaligned-access, + and -mstrict-align affect this macro correctly. + Clang >= 17 supports -mno-strict-align too. + + - ARM64 + GCC: It partially works. The macro + is always #defined by GCC versions at least + up to 13.2, even when using -mstrict-align. + If building for strict-align ARM64, the + configure option --disable-unaligned-access + should be used if using a GCC version that has + this issue because otherwise the performance + may be degraded. It likely won't crash due to + how unaligned access is done in the C code. --enable-unsafe-type-punning This enables use of code like diff --git a/m4/tuklib_integer.m4 b/m4/tuklib_integer.m4 index ab9a4056..89a53fe1 100644 --- a/m4/tuklib_integer.m4 +++ b/m4/tuklib_integer.m4 @@ -65,22 +65,42 @@ AC_MSG_CHECKING([if unaligned memory access should be used]) AC_ARG_ENABLE([unaligned-access], AS_HELP_STRING([--enable-unaligned-access], [Enable if the system supports *fast* unaligned memory access with 16-bit, 32-bit, and 64-bit integers. By default, - this is enabled only on x86, x86_64, big endian PowerPC, - and some ARM systems.]), + this is enabled on x86, x86-64, + 32/64-bit big endian PowerPC, + 64-bit little endian PowerPC, + and some ARM, ARM64, and RISC-V systems.]), [], [enable_unaligned_access=auto]) if test "x$enable_unaligned_access" = xauto ; then - # TODO: There may be other architectures, on which unaligned access - # is OK. + # NOTE: There might be other architectures on which unaligned access + # is fast. case $host_cpu in - i?86|x86_64|powerpc|powerpc64) + i?86|x86_64|powerpc|powerpc64|powerpc64le) enable_unaligned_access=yes ;; - arm*|aarch64*) + arm*|aarch64*|riscv*) # On 32-bit and 64-bit ARM, GCC and Clang # #define __ARM_FEATURE_UNALIGNED if # unaligned access is supported. + # + # Exception: GCC at least up to 13.2.0 + # defines it even when using -mstrict-align + # so in that case this autodetection goes wrong. + # Most of the time -mstrict-align isn't used so it + # shouldn't be a common problem in practice. See: + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111555 + # + # RISC-V C API Specification says that if + # __riscv_misaligned_fast is defined then + # unaligned access is known to be fast. + # + # MSVC is handled as a special case: We assume that + # 32/64-bit ARM supports fast unaligned access. + # If MSVC gets RISC-V support then this will assume + # fast unaligned access on RISC-V too. AC_COMPILE_IFELSE([AC_LANG_SOURCE([ -#ifndef __ARM_FEATURE_UNALIGNED +#if !defined(__ARM_FEATURE_UNALIGNED) \ + && !defined(__riscv_misaligned_fast) \ + && !defined(_MSC_VER) compile error #endif int main(void) { return 0; }