mariadb/mysys/crc32
J. Neuschäfer 305576e9c6 Fix NEON-optimized crc32 on big-endian
For the algorithms in crc32_arm64.c to work consistenly, all multibyte
integers loaded from the input buffer have to be loaded in little-endian.

Tested on an aarch64_be-unknown-linux-musl system, with:

  ninja crc32-t && unittest/mysys/crc32-t

Test results:

unpatched:
+------------------------------------+-------------------+--------------------+
| Code path                          | GCC 15.2.0        | Clang 20.1.8       |
+------------------------------------+-------------------+--------------------+
|`crc32c_aarch64`                    | 25 failed tests   | 25 failed tests    |
+------------------------------------+-------------------+--------------------+
|`crc32c_aarch64_pmull` (assembly)   | 25 failed tests   | doesn't compile    |
+------------------------------------+-------------------+--------------------+
|`crc32c_aarch64_pmull` (intrinsics) | 25 failed tests   | 26 failed tests    |
+------------------------------------+-------------------+--------------------+

patched:
+------------------------------------+-------------------+--------------------+
| Code path                          | GCC 15.2.0        | Clang 20.1.8       |
+------------------------------------+-------------------+--------------------+
|`crc32c_aarch64`                    | success           | success            |
+------------------------------------+-------------------+--------------------+
|`crc32c_aarch64_pmull` (assembly)   | success           | doesn't compile    |
+------------------------------------+-------------------+--------------------+
|`crc32c_aarch64_pmull` (intrinsics) | success           | 1 failed test      |
+------------------------------------+-------------------+--------------------+

Implementation notes:

- uintNkorr uses the byte-wise implementation of a fixed-endian load,
  which can't always be turned back into a single load instruction.
  On aarch64-unknown-linux-musl (little endian) with GCC 15.2, this
  resulted in a code pessimization at -O0 and -O1, but -Os and -O2 are
  fine, so this is not a problem.
  On MSVC/Windows there does appear to be a pessimization[1].

- Using le16toh etc. are a potential alternative, as these macros are
  no-ops on little-endian platforms that support them. The endian(3)
  manpage suggests that NetBSD, FreeBSD, and glibc (in addition to
  musl), but not OpenBSD, support them[2]. Windows support is unclear.
  leNNtoh has the added disadvantage of being unusual in the MariaDB
  codebase, so it's better to stick with uintNkorr.

[1]: https://godbolt.org/z/oncv9Gj19
[2]: https://man.he.net/man3/htole64
2025-10-02 15:44:34 +03:00
..
clang_workaround.h MDEV-22641: Provide SIMD optimized wrapper for zlib crc32() (#1558) 2020-06-01 11:34:06 +03:00
crc32_arm64.c Fix NEON-optimized crc32 on big-endian 2025-10-02 15:44:34 +03:00
crc32_ppc64.c MDEV-19935 Create unified CRC-32 interface 2020-09-17 16:07:37 +02:00
crc32_x86.c MDEV-33817 preparation: Restructuring and unit tests 2024-05-03 13:06:13 +03:00
crc32c.cc Enable use of elf_aux_info() to detect CPU features on aarch64 and powerpc64 2025-06-14 17:39:01 +10:00
crc32c_amd64.cc MDEV-34321: call to crc32c_3way through pointer to incorrect function type 2024-06-07 13:51:46 +03:00
crc32c_ppc.c MDEV-19935 Create unified CRC-32 interface 2020-09-17 16:07:37 +02:00
crc32c_ppc.h MDEV-33817 preparation: Restructuring and unit tests 2024-05-03 13:06:13 +03:00
crc32c_x86.cc MDEV-33817/MDEV-37170 fixup: Remove evex512 2025-08-30 19:28:16 +03:00
crc_ppc64.h MDEV-33817 preparation: Restructuring and unit tests 2024-05-03 13:06:13 +03:00
pcc_crc32_constants.h MDEV-22641: Provide SIMD optimized wrapper for zlib crc32() (#1558) 2020-06-01 11:34:06 +03:00
pcc_crc32c_constants.h MDEV-22641: Provide SIMD optimized wrapper for zlib crc32() (#1558) 2020-06-01 11:34:06 +03:00