In aarch64, the strnlen interface has a problem when the string length is more than 9
*** Bug 25825 has been marked as a duplicate of this bug. ***
There is a testcase. #include <stdio.h> #include <string.h> void init_base(char *base, int len) { int i; for (i = 0; i < len; i++) { base[i] = 'x'; } base[len] = '\0'; } int main(int argc, char *argv[]) { int i; char base[1000]; char buff[1000]; size_t n; for (i = 1; i < 1000; i++) { memset(buff, 0, 1000); init_base(base, i); n = strnlen(base, 1000); if ( i == n ) printf("size=%d is equel\n", i); else printf("size=%d is not equel%s\n", i); } return 0; } The execution log is as follows: arm64be /tmp # ./arm64be-test_strnlen size=1 is equel size=2 is equel size=3 is equel size=4 is equel size=5 is equel size=6 is equel size=7 is equel size=8 is equel size=9 is not equel size=10 is not equel size=11 is not equel size=12 is not equel size=13 is not equel
This does not fail on little-endian aarch64.
(In reply to Yan Zhu from comment #0) > In aarch64, the strnlen interface has a problem when the string length is > more than 9 In big-endian? Yes that rev64 only swaps bytes in each 64-bit word, so you still need to swap the index in mov data1, datav2.d[0]. This sequence comes from strlen_asimd.S originally. And now strcpy.S has it too.
(In reply to Wilco from comment #5) > (In reply to Yan Zhu from comment #0) > > In aarch64, the strnlen interface has a problem when the string length is > > more than 9 > > In big-endian? Yes that rev64 only swaps bytes in each 64-bit word, so you > still need to swap the index in mov data1, datav2.d[0]. > > This sequence comes from strlen_asimd.S originally. And now strcpy.S has it > too. Btw I have a faster strnlen I'll post soon that will fix one of the 3 cases.
bigendian strnlen, strcpy (and stpcpy) are fixed for glibc 2.32 in commit 59b64f9cbbf1e98c6d187873de6c363994aee19d Author: Lexi Shao <shaolexi@huawei.com> AuthorDate: 2020-05-15 18:48:59 +0800 aarch64: fix strcpy and strnlen for big-endian [BZ #25824] falkor and kunpeng920 specific strlen_asimd still needs to be fixed.
The master branch has been updated by Wilco Dijkstra <wilco@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=f46ef33ad134bec7ac992f28ee4b8b0614590e3e commit f46ef33ad134bec7ac992f28ee4b8b0614590e3e Author: Wilco Dijkstra <wdijkstr@arm.com> Date: Fri Jul 17 14:09:36 2020 +0100 AArch64: Improve strlen_asimd performance (bug 25824) Optimize strlen using a mix of scalar and SIMD code. On modern micro architectures large strings are 2.6 times faster than existing strlen_asimd and 35% faster than the new MTE version of strlen. On a random strlen benchmark using small sizes the speedup is 7% vs strlen_asimd and 40% vs the MTE strlen. This fixes the main strlen regressions on Cortex-A53 and other cores with a simple Neon unit. Rename __strlen_generic to __strlen_mte, and select strlen_asimd when MTE is not enabled (this is waiting on support for a HWCAP_MTE bit). This fixes big-endian bug 25824. Passes GLIBC regression tests. Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
fixed for 2.32