@@ -3725,6 +3725,40 @@ static zend_always_inline void zend_memnstr_ex_pre(unsigned int td[], const char
37253725
37263726ZEND_API const char * ZEND_FASTCALL zend_memnstr_ex (const char * haystack , const char * needle , size_t needle_len , const char * end ) /* {{{ */
37273727{
3728+ #if defined(__SSE2__ )
3729+ if (needle_len >= 4 ) {
3730+ const char * p ;
3731+ __m128i first_chars = _mm_set1_epi8 (needle [0 ]);
3732+ __m128i last_chars = _mm_set1_epi8 (needle [needle_len - 1 ]);
3733+
3734+ for (p = haystack ; p <= end - needle_len ; p += 16 ) {
3735+ __m128i haystack_first_chars = _mm_loadu_si128 ((__m128i * )p );
3736+ __m128i haystack_last_chars = _mm_loadu_si128 ((__m128i * )(p + needle_len - 1 ));
3737+ __m128i eq_first = _mm_cmpeq_epi8 (first_chars , haystack_first_chars );
3738+ __m128i eq_last = _mm_cmpeq_epi8 (last_chars , haystack_last_chars );
3739+ unsigned long mask = _mm_movemask_epi8 (_mm_and_si128 (eq_first , eq_last ));
3740+
3741+ while (mask > 0 ) {
3742+ unsigned long bit = 1UL << __builtin_ctzl (mask );
3743+ size_t ofs = __builtin_ctzl (mask );
3744+ if (memcmp (p + ofs + 1 , needle + 1 , needle_len - 2 ) == 0 ) {
3745+ return p + ofs ;
3746+ }
3747+ mask &= ~bit ;
3748+ }
3749+ }
3750+
3751+ // Handle the remainder of the string if its length is not a multiple of 16
3752+ for (; p <= end - needle_len ; p ++ ) {
3753+ if (p [0 ] == needle [0 ] && memcmp (p + 1 , needle + 1 , needle_len - 1 ) == 0 ) {
3754+ return p ;
3755+ }
3756+ }
3757+
3758+ return NULL ;
3759+ }
3760+ #endif
3761+
37283762 unsigned int td [256 ];
37293763 size_t i ;
37303764 const char * p ;
@@ -3739,12 +3773,7 @@ ZEND_API const char* ZEND_FASTCALL zend_memnstr_ex(const char *haystack, const c
37393773 end -= needle_len ;
37403774
37413775 while (p <= end ) {
3742- for (i = 0 ; i < needle_len ; i ++ ) {
3743- if (needle [i ] != p [i ]) {
3744- break ;
3745- }
3746- }
3747- if (i == needle_len ) {
3776+ if (memcmp (p , needle , needle_len ) == 0 ) {
37483777 return p ;
37493778 }
37503779 if (UNEXPECTED (p == end )) {
0 commit comments