Fix memchr with a zero length.

The memchr implementation for 64 bit fails if these conditions occur:

- The buffer is 32 byte aligned.
- The buffer contains the character in the first byte.
- The count sent in is zero.

The function should return NULL, but it's not.

Bug: 16676625

(cherry picked from commit e03e1eac0b7682884b6628df1305d34299680cb4)

Change-Id: Ie4cca2c445127a0936ee2b96651a8e7204fbaffd
diff --git a/libc/arch-arm64/generic/bionic/memchr.S b/libc/arch-arm64/generic/bionic/memchr.S
index fbb00ca..e5ea57d 100644
--- a/libc/arch-arm64/generic/bionic/memchr.S
+++ b/libc/arch-arm64/generic/bionic/memchr.S
@@ -75,6 +75,7 @@
 	 * Magic constant 0x40100401 allows us to identify which lane matches
 	 * the requested byte.
 	 */
+	cbz	cntin, .Lzero_length
 	mov	wtmp2, #0x0401
 	movk	wtmp2, #0x4010, lsl #16
 	dup	vrepchr.16b, chrin
@@ -157,4 +158,8 @@
 	/* Select result or NULL */
 	csel	result, xzr, result, eq
 	ret
+
+.Lzero_length:
+	mov	result, xzr
+	ret
 END(memchr)
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index bc2c05b..73c94c6 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -763,6 +763,14 @@
   }
 }
 
+TEST(string, memchr_zero) {
+  uint8_t* buffer;
+  ASSERT_EQ(0, posix_memalign(reinterpret_cast<void**>(&buffer), 64, 64));
+  memset(buffer, 10, 64);
+  ASSERT_TRUE(NULL == memchr(buffer, 5, 0));
+  ASSERT_TRUE(NULL == memchr(buffer, 10, 0));
+}
+
 TEST(string, memrchr) {
   int seek_char = random() & 255;
   StringTestState<char> state(SMALL);