Hi all, PostgreSQL currently has hardware-accelerated CRC-32C on x86_64 (SSE 4.2 / AVX-512), ARMv8 and LoongArch, but on RISC-V we always fall back to the software slicing-by-8 implementation. Some RISC-V CPUs implement the Zbc extension, which adds carry-less multiplication instructions (clmul/clmulh). CRC-32C can be computed with a folding algorithm built on carry-less multiplication, so these CPUs can get hardware acceleration too, which should help in IO-heavy workloads. Attached is a patch that adds RISC-V Zbc support for CRC-32C, following roughly the same structure as the existing ARMv8 implementation (commit f044d71e331d): src/port/pg_crc32c_zbc.c does the folding algorithm using the __builtin_rev_crc32_data8/16/32() compiler intrinsics. These landed in GCC 15 and compile down to clmul-based sequences when targeting Zbc. As in the ARMv8 version, we process leading bytes one at a time until the pointer is 8-byte aligned, run the main loop eight bytes at a time, then handle the trailing 0-7 bytes. src/port/pg_crc32c_zbc_choose.c does the runtime check. Zbc has no corresponding bit in the auxiliary vector, so we probe for it by running the clmul code and catching SIGILL — same approach as pg_crc32c_armv8_choose.c. If that fails we fall back to slicing-by-8. configure checks for the intrinsics first with the default compiler flags, then with "-march=rv64gc_zbc" if that fails. We build with the runtime-check path whenever the compiler supports the intrinsics at all, since compilers generally don't target Zbc by default. The hardware-specific code lives behind #if defined USE_ZBC_CRC32C_WITH_RUNTIME_CHECK. I benchmarked this with pgbench TPC-B (scale 4000) under QEMU (qemu-riscv64, CPU model xt-c9501fdvkt), using the QEMU hotblocks plugin to count instructions over the same workload: baseline (SB8) Zbc clmul total instructions 1,787,477,187 1,721,911,819 (-3.67%) XLogRecordAssemble 168,329,617 50,044,718 pg_comp_crc32c_zbc N/A 85,984,082 Most of the reduction comes from the CRC32C computation itself — compared to the ARMv8 hardware path on the same workload (76.6M instructions), this closes 85.7% of the gap. I checked correctness against slicing-by-8 on 584 test vectors (all input lengths 0-72 at every alignment offset, two different initial CRC values), and ran the full pgbench workload with WAL CRC validation enabled, which passed. The patch applies against master's current CRC-32C layout and also applies cleanly to REL_17. I'll add it to the next CommitFest. Feedback welcome. Regards, Jun Sha
0001-Add-RISC-V-Zbc-clmul-CRC-32C-implementation.patch
Description: Binary data
