diff --git a/src/port/pg_crc32c_armv8.c b/src/port/pg_crc32c_armv8.c index 5fa57fb4927..8cf838a510a 100644 --- a/src/port/pg_crc32c_armv8.c +++ b/src/port/pg_crc32c_armv8.c @@ -91,6 +91,7 @@ pg_comp_crc32c_armv8(pg_crc32c crc, const void *data, size_t len) * - match our function declaration * - match whitespace to our project style * - be more friendly for pgindent + * - exit early for small inputs */ /* Generated by https://github.com/corsix/fast-crc32/ using: */ @@ -127,19 +128,28 @@ pg_comp_crc32c_pmull(pg_crc32c crc, const void *data, size_t len) pg_crc32c crc0 = crc; const char *buf = data; + /* + * Immediately fall back to the scalar path if the vector path is not + * guaranteed to perform at least one iteration after the alignment + * preamble. + */ + if (len < 5 * sizeof(uint64x2_t)) + return pg_comp_crc32c_armv8(crc, data, len); + /* align to 16 bytes */ - for (; len && ((uintptr_t) buf & 7); --len) + for (; (uintptr_t) buf & 7; --len) { crc0 = __crc32cb(crc0, *buf++); } - if (((uintptr_t) buf & 8) && len >= 8) + if ((uintptr_t) buf & 8) { crc0 = __crc32cd(crc0, *(const uint64_t *) buf); buf += 8; len -= 8; } - if (len >= 64) + Assert(len >= 64); + { const char *end = buf + len; const char *limit = buf + len - 64;