--- a/sys/libkern/memcchr.c +++ b/sys/libkern/memcchr.c @@ -74,33 +74,33 @@ /* Don't perform memory I/O when passing a zero-length buffer. */ if (n == 0) return (NULL); - /* - * First determine whether there is a character unequal to `c' - * in the first word. As this word may contain bytes before - * `begin', we may execute this loop spuriously. - */ - lp = (const unsigned long *)((uintptr_t)begin & ~LONGPTR_MASK); end = (const unsigned char *)begin + n; - if (*lp++ != word) - for (p = begin; p < (const unsigned char *)lp;) - TESTBYTE; - /* Now compare the data one word at a time. */ - for (; (const unsigned char *)lp < end; lp++) { + /* Compare bytewise until word aligned: no loads below begin. */ + for (p = begin; p < end && ((uintptr_t)p & LONGPTR_MASK);) + TESTBYTE; + + /* Compare one word at a time while the whole word is in range. */ + for (lp = (const unsigned long *)p; + (const unsigned char *)(lp + 1) <= end; lp++) { if (*lp != word) { p = (const unsigned char *)lp; TESTBYTE; TESTBYTE; TESTBYTE; #if LONG_BIT >= 64 TESTBYTE; TESTBYTE; TESTBYTE; TESTBYTE; #endif goto done; } } + /* Trailing bytes: no loads past end. */ + for (p = (const unsigned char *)lp; p < end;) + TESTBYTE; + return (NULL);