]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Exit early from pg_comp_crc32c_pmull for small inputs
authorJohn Naylor <john.naylor@postgresql.org>
Wed, 8 Apr 2026 06:52:14 +0000 (13:52 +0700)
committerJohn Naylor <john.naylor@postgresql.org>
Wed, 8 Apr 2026 06:52:14 +0000 (13:52 +0700)
The vectorized path in commit fbc57f2bc had a side effect of putting
more branches in the path taken for small inputs. To reduce risk
of regressions, only proceed with the vectorized path if we can
guarantee that the remaining input after the alignment preamble is
greater than 64 bytes. That also allows removing length checks in
the alignment preamble.

Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Discussion: https://postgr.es/m/CANWCAZZ48GuLYhJCcTy8TXysjrMVJL6n1n7NP94=iG+t80YKPw@mail.gmail.com

src/port/pg_crc32c_armv8.c

index 5fa57fb492701a39fb8de570796effd95e2d022e..8cf838a510a21d3ee3ce091cb56d38d18bfcf2ec 100644 (file)
@@ -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;