Commit 06de9aeef7 for perl

commit 06de9aeef7494843350fdff25194f0dcc5945b5a
Author: Richard Leach <rich+perl@hyphen-dash-hyphen.info>
Date:   Sat Oct 3 22:47:02 2026 +0000

    S_find_next_masked: boost the word-at-a-time performance

    The throughput of this loop was markedly lower than the word-at-a-time
    loop in `S_find_span_end_mask`, as can be seen by comparing the
    measurements from the previous couple of commits.

    This commit tweaks that look to bring throughput of `S_find_next_masked`
    up to the level of `S_find_span_end_mask`.

    Before:
    * find_next_masked    /\A[^A]+/ 4741/s

    Now:
    * find_next_masked    /\A[^A]+/ 9261/s

    Still trumped by the step up to 512-bit scanning:
    * find_next_masked    \A[^A]+/ 16365/s

    Still nice for the word-at-a-time loop to be zippier when finding the
    actual position though.

diff --git a/regexec.c b/regexec.c
index f3896cb924..a3ec5c6ac8 100644
--- a/regexec.c
+++ b/regexec.c
@@ -832,38 +832,18 @@ S_find_next_masked(U8 * s, const U8 * send, const U8 byte, const U8 mask)
         PERL_UINTMAX_T word = PERL_COUNT_MULTIPLIER * byte;
         PERL_UINTMAX_T mask_word = PERL_COUNT_MULTIPLIER * mask;

+        /* Process per-word as long as we have at least a full word left */
         while (s + PERL_WORDSIZE <= send) {
-            PERL_UINTMAX_T masked = (* (PERL_UINTMAX_T *) s) & mask_word;
-
-            /* If 'masked' contains bytes with the bit pattern of 'byte' within
-             * it, xoring with 'word' will leave each of the 8 bits in such
-             * bytes be 0, and no byte containing any other bit pattern will be
-             * 0. */
-            masked ^= word;
-
-            /* This causes the most significant bit to be set to 1 for any
-             * bytes in the word that aren't completely 0 */
-            masked |= masked << 1;
-            masked |= masked << 2;
-            masked |= masked << 4;
-
-            /* The msbits are the same as what marks a byte as variant, so we
-             * can use this mask.  If all msbits are 1, the word doesn't
-             * contain 'byte' */
-            if ((masked & PERL_VARIANTS_WORD_MASK) == PERL_VARIANTS_WORD_MASK) {
+            /* "masked" has zero byte where the mask matched. */
+            PERL_UINTMAX_T masked = ((* (PERL_UINTMAX_T *) s) & mask_word) ^ word;
+            /* "hits" has the high bit set where there were any zeroes. */
+            PERL_UINTMAX_T hits = (masked - PERL_COUNT_MULTIPLIER) & ~masked
+                                                     & PERL_VARIANTS_WORD_MASK;
+            if (hits == 0) {
                 s += PERL_WORDSIZE;
                 continue;
             }
-
-            /* Here, the msbit of bytes in the word that aren't 'byte' are 1,
-             * and any that are, are 0.  Complement and re-AND to swap that */
-            masked = ~ masked;
-            masked &= PERL_VARIANTS_WORD_MASK;
-
-            /* This reduces the problem to that solved by this function */
-            s += variant_byte_number(masked);
-            return s;
-
+            return s + first_upper_bit_set_byte_number(hits);
         }
     }