[PATCH v3 00/17] riscv: Add RVV str*/mem* routines
Yao Zihong
zihong.plct@isrc.iscas.ac.cn
Tue Dec 30 15:30:27 GMT 2025
Changes since v2:
* Fixed symbol export issues
* Rebased onto the current RVV multiarch and non-multiarch framework
* Added RVV implementations for memccpy, memrchr and strrchr
* Adjusted register usage for Zca-friendliness
* Improved label naming for readability
Changes since v1:
* Wrapped RVV assembly with `#if IS_IN (libc)` so that rtld/* does not
include vectorized code.
* Added `.option push` / `.option arch, +v` / `.option pop` around
vectorized functions, so builds succeed even when compilers are
invoked without global +v support.
Hi all,
This series introduces RVV implementations for the RISC-V str*/mem* family
within current RVV multiarch and non-multiarch framework.
Background
----------
This series is a rework and extension of Hau Hsu's v3 RVV patches [1],
adapted to the current RVV multiarch and non-multiarch framework, and
fixing issues in the previous patch series [2].
In addition to the original set, this series also adds RVV implementations
for memccpy, memrchr and strrchr.
---
Testing
-------
Testing was conducted on MUSE-Pi (SpacemiT M1). The glibc testsuite passed
without any additional regressions compared with glibc master in multiarch
and non-multiarch builds when the RVV extension was not disabled via prctl().
Summary of test results for(MUSE-Pi):
XFAIL: conform/UNIX98/ndbm.h/conform
XFAIL: conform/UNIX98/ndbm.h/linknamespace
XFAIL: conform/UNIX98/varargs.h/conform
XFAIL: conform/UNIX98/varargs.h/linknamespace
XFAIL: conform/XOPEN2K/ndbm.h/conform
XFAIL: conform/XOPEN2K/ndbm.h/linknamespace
XFAIL: conform/XOPEN2K8/ndbm.h/conform
XFAIL: conform/XOPEN2K8/ndbm.h/linknamespace
XFAIL: conform/XPG4/varargs.h/conform
XFAIL: conform/XPG4/varargs.h/linknamespace
XFAIL: conform/XPG42/ndbm.h/conform
XFAIL: conform/XPG42/ndbm.h/linknamespace
XFAIL: conform/XPG42/varargs.h/conform
XFAIL: conform/XPG42/varargs.h/linknamespace
UNSUPPORTED: elf/tst-env-setuid
XPASS: elf/tst-protected1a
XPASS: elf/tst-protected1b
UNSUPPORTED: elf/tst-valgrind-smoke
UNSUPPORTED: io/tst-faccessat-setuid
UNSUPPORTED: libio/tst-fopen-compat
XFAIL: localedata/tst-langinfo-newlocale-static
UNSUPPORTED: math/test-ceil-except-2
UNSUPPORTED: math/test-fesetexcept-traps
UNSUPPORTED: math/test-fexcept-traps
UNSUPPORTED: math/test-floor-except-2
UNSUPPORTED: math/test-nearbyint-except-2
UNSUPPORTED: math/test-trunc-except-2
UNSUPPORTED: misc/tst-adjtimex
UNSUPPORTED: misc/tst-clock_adjtime
UNSUPPORTED: misc/tst-epoll-ioctls
FAIL: misc/tst-gethostid
UNSUPPORTED: misc/tst-mseal
UNSUPPORTED: misc/tst-mseal-pkey
UNSUPPORTED: misc/tst-ntp_adjtime
UNSUPPORTED: misc/tst-pidfd_getinfo
UNSUPPORTED: misc/tst-pkey
UNSUPPORTED: nptl/test-cond-printers
UNSUPPORTED: nptl/test-condattr-printers
UNSUPPORTED: nptl/test-mutex-printers
UNSUPPORTED: nptl/test-mutexattr-printers
UNSUPPORTED: nptl/test-rwlock-printers
UNSUPPORTED: nptl/test-rwlockattr-printers
FAIL: nss/test-netdb
XFAIL: posix/annexc
FAIL: resolv/tst-bug18665
FAIL: resolv/tst-bug18665-tcp
FAIL: resolv/tst-ns_rr_cursor
FAIL: resolv/tst-resolv-ai_idn
FAIL: resolv/tst-resolv-ai_idn-latin1
FAIL: resolv/tst-resolv-ai_idn-nolibidn2
FAIL: resolv/tst-resolv-aliases
FAIL: resolv/tst-resolv-basic
FAIL: resolv/tst-resolv-byaddr
FAIL: resolv/tst-resolv-invalid-cname
FAIL: resolv/tst-resolv-noaaaa
FAIL: resolv/tst-resolv-noaaaa-vc
FAIL: resolv/tst-resolv-res_init-multi
FAIL: resolv/tst-resolv-search
FAIL: resolv/tst-resolv-semi-failure
FAIL: resolv/tst-resolv-short-response
FAIL: resolv/tst-resolv-threads
UNSUPPORTED: string/tst-strerror
UNSUPPORTED: string/tst-strsignal
UNSUPPORTED: time/tst-clock_settime
UNSUPPORTED: time/tst-settimeofday
=== Summary of results ===
19 FAIL
6644 PASS
28 UNSUPPORTED
16 XFAIL
2 XPASS
---
Performance
----------
Measured overall performance improvements of the vectorized ("rvv")
implementations vs. the existing Glibc ("scalar") implementations are as
follows:
memccpy: 49% time savings (i.e., if scalar is 100ms, then rvv is 51ms)
memrchr: 58%
strrchr: 39%
Above data are collected on SpacemiT M1, with glibc existing benchtests.
The performance improvements for the rest of the routines are listed in[1].
Reference
----------
[1] https://inbox.sourceware.org/libc-alpha/20230504074851.38763-1-hau.hsu@sifive.com/
[2] https://inbox.sourceware.org/libc-alpha/20250930003543.86600-1-zihong.plct@isrc.iscas.ac.cn/
---
Yao Zihong (17):
riscv: Add RVV memccpy for multiarch and non-multiarch
riscv: Add RVV memchr for multiarch and non-multiarch
riscv: Add RVV memcmp for multiarch and non-multiarch
riscv: Add RVV memcmpeq for multiarch and non-multiarch
riscv: Add RVV memcpy for multiarch and non-multiarch
riscv: Add RVV memmove for multiarch and non-multiarch
riscv: Add RVV memrchr for multiarch and non-multiarch
riscv: Add RVV strcat for multiarch and non-multiarch
riscv: Add RVV strchr for multiarch and non-multiarch
riscv: Add RVV strcmp for multiarch and non-multiarch
riscv: Add RVV strcpy for multiarch and non-multiarch
riscv: Add RVV strlen for multiarch and non-multiarch
riscv: Add RVV strncat for multiarch and non-multiarch
riscv: Add RVV strncmp for multiarch and non-multiarch
riscv: Add RVV strncpy for multiarch and non-multiarch
riscv: Add RVV strnlen for multiarch and non-multiarch
riscv: Add RVV strrchr for multiarch and non-multiarch
.../riscv/multiarch/dl-symbol-redir-ifunc.h | 1 +
sysdeps/riscv/multiarch/memccpy-generic.c | 26 ++++
sysdeps/riscv/multiarch/memccpy-vector.S | 30 +++++
sysdeps/riscv/multiarch/memchr-generic.c | 24 ++++
sysdeps/riscv/multiarch/memchr-vector.S | 30 +++++
sysdeps/riscv/multiarch/memcmp-generic.c | 31 +++++
sysdeps/riscv/multiarch/memcmp-vector.S | 30 +++++
sysdeps/riscv/multiarch/memcmpeq-generic.c | 31 +++++
sysdeps/riscv/multiarch/memcmpeq-vector.S | 30 +++++
sysdeps/riscv/multiarch/memcpy-vector.S | 30 +++++
sysdeps/riscv/multiarch/memmove-generic.c | 26 ++++
sysdeps/riscv/multiarch/memmove-vector.S | 30 +++++
sysdeps/riscv/multiarch/memrchr-generic.c | 28 ++++
sysdeps/riscv/multiarch/memrchr-vector.S | 30 +++++
sysdeps/riscv/multiarch/strcat-generic.c | 26 ++++
sysdeps/riscv/multiarch/strcat-vector.S | 30 +++++
sysdeps/riscv/multiarch/strchr-generic.c | 24 ++++
sysdeps/riscv/multiarch/strchr-vector.S | 30 +++++
sysdeps/riscv/multiarch/strcmp-generic.c | 24 ++++
sysdeps/riscv/multiarch/strcmp-vector.S | 30 +++++
sysdeps/riscv/multiarch/strcpy-generic.c | 26 ++++
sysdeps/riscv/multiarch/strcpy-vector.S | 30 +++++
sysdeps/riscv/multiarch/strlen-generic.c | 24 ++++
sysdeps/riscv/multiarch/strlen-vector.S | 30 +++++
sysdeps/riscv/multiarch/strncat-generic.c | 26 ++++
sysdeps/riscv/multiarch/strncat-vector.S | 30 +++++
sysdeps/riscv/multiarch/strncmp-generic.c | 26 ++++
sysdeps/riscv/multiarch/strncmp-vector.S | 30 +++++
sysdeps/riscv/multiarch/strncpy-generic.c | 26 ++++
sysdeps/riscv/multiarch/strncpy-vector.S | 30 +++++
sysdeps/riscv/multiarch/strnlen-generic.c | 24 ++++
sysdeps/riscv/multiarch/strnlen-vector.S | 30 +++++
sysdeps/riscv/multiarch/strrchr-generic.c | 28 ++++
sysdeps/riscv/multiarch/strrchr-vector.S | 30 +++++
sysdeps/riscv/riscv-ifunc.h | 4 +
sysdeps/riscv/rvv/memccpy.S | 67 ++++++++++
sysdeps/riscv/rvv/memchr.S | 67 ++++++++++
sysdeps/riscv/rvv/memcmp.S | 84 ++++++++++++
sysdeps/riscv/rvv/memcmpeq.S | 67 ++++++++++
sysdeps/riscv/rvv/memcpy.S | 54 ++++++++
sysdeps/riscv/rvv/memmove.S | 74 +++++++++++
sysdeps/riscv/rvv/memrchr.S | 71 ++++++++++
sysdeps/riscv/rvv/strcat.S | 75 +++++++++++
sysdeps/riscv/rvv/strchr.S | 65 +++++++++
sysdeps/riscv/rvv/strcmp.S | 93 +++++++++++++
sysdeps/riscv/rvv/strcpy.S | 59 +++++++++
sysdeps/riscv/rvv/strlen.S | 58 +++++++++
sysdeps/riscv/rvv/strncat.S | 81 ++++++++++++
sysdeps/riscv/rvv/strncmp.S | 88 +++++++++++++
sysdeps/riscv/rvv/strncpy.S | 89 +++++++++++++
sysdeps/riscv/rvv/strnlen.S | 61 +++++++++
sysdeps/riscv/rvv/strrchr.S | 123 ++++++++++++++++++
.../unix/sysv/linux/riscv/multiarch/Makefile | 49 +++++++
.../linux/riscv/multiarch/ifunc-impl-list.c | 82 ++++++++++++
.../unix/sysv/linux/riscv/multiarch/memccpy.c | 58 +++++++++
.../unix/sysv/linux/riscv/multiarch/memchr.c | 57 ++++++++
.../unix/sysv/linux/riscv/multiarch/memcmp.c | 60 +++++++++
.../sysv/linux/riscv/multiarch/memcmpeq.c | 50 +++++++
.../unix/sysv/linux/riscv/multiarch/memcpy.c | 5 +
.../unix/sysv/linux/riscv/multiarch/memmove.c | 56 ++++++++
.../unix/sysv/linux/riscv/multiarch/memrchr.c | 50 +++++++
.../unix/sysv/linux/riscv/multiarch/strcat.c | 56 ++++++++
.../unix/sysv/linux/riscv/multiarch/strchr.c | 58 +++++++++
.../unix/sysv/linux/riscv/multiarch/strcmp.c | 56 ++++++++
.../unix/sysv/linux/riscv/multiarch/strcpy.c | 56 ++++++++
.../unix/sysv/linux/riscv/multiarch/strlen.c | 56 ++++++++
.../unix/sysv/linux/riscv/multiarch/strncat.c | 52 ++++++++
.../unix/sysv/linux/riscv/multiarch/strncmp.c | 56 ++++++++
.../unix/sysv/linux/riscv/multiarch/strncpy.c | 56 ++++++++
.../unix/sysv/linux/riscv/multiarch/strnlen.c | 56 ++++++++
.../unix/sysv/linux/riscv/multiarch/strrchr.c | 59 +++++++++
71 files changed, 3239 insertions(+)
create mode 100644 sysdeps/riscv/multiarch/memccpy-generic.c
create mode 100644 sysdeps/riscv/multiarch/memccpy-vector.S
create mode 100644 sysdeps/riscv/multiarch/memchr-generic.c
create mode 100644 sysdeps/riscv/multiarch/memchr-vector.S
create mode 100644 sysdeps/riscv/multiarch/memcmp-generic.c
create mode 100644 sysdeps/riscv/multiarch/memcmp-vector.S
create mode 100644 sysdeps/riscv/multiarch/memcmpeq-generic.c
create mode 100644 sysdeps/riscv/multiarch/memcmpeq-vector.S
create mode 100644 sysdeps/riscv/multiarch/memcpy-vector.S
create mode 100644 sysdeps/riscv/multiarch/memmove-generic.c
create mode 100644 sysdeps/riscv/multiarch/memmove-vector.S
create mode 100644 sysdeps/riscv/multiarch/memrchr-generic.c
create mode 100644 sysdeps/riscv/multiarch/memrchr-vector.S
create mode 100644 sysdeps/riscv/multiarch/strcat-generic.c
create mode 100644 sysdeps/riscv/multiarch/strcat-vector.S
create mode 100644 sysdeps/riscv/multiarch/strchr-generic.c
create mode 100644 sysdeps/riscv/multiarch/strchr-vector.S
create mode 100644 sysdeps/riscv/multiarch/strcmp-generic.c
create mode 100644 sysdeps/riscv/multiarch/strcmp-vector.S
create mode 100644 sysdeps/riscv/multiarch/strcpy-generic.c
create mode 100644 sysdeps/riscv/multiarch/strcpy-vector.S
create mode 100644 sysdeps/riscv/multiarch/strlen-generic.c
create mode 100644 sysdeps/riscv/multiarch/strlen-vector.S
create mode 100644 sysdeps/riscv/multiarch/strncat-generic.c
create mode 100644 sysdeps/riscv/multiarch/strncat-vector.S
create mode 100644 sysdeps/riscv/multiarch/strncmp-generic.c
create mode 100644 sysdeps/riscv/multiarch/strncmp-vector.S
create mode 100644 sysdeps/riscv/multiarch/strncpy-generic.c
create mode 100644 sysdeps/riscv/multiarch/strncpy-vector.S
create mode 100644 sysdeps/riscv/multiarch/strnlen-generic.c
create mode 100644 sysdeps/riscv/multiarch/strnlen-vector.S
create mode 100644 sysdeps/riscv/multiarch/strrchr-generic.c
create mode 100644 sysdeps/riscv/multiarch/strrchr-vector.S
create mode 100644 sysdeps/riscv/rvv/memccpy.S
create mode 100644 sysdeps/riscv/rvv/memchr.S
create mode 100644 sysdeps/riscv/rvv/memcmp.S
create mode 100644 sysdeps/riscv/rvv/memcmpeq.S
create mode 100644 sysdeps/riscv/rvv/memcpy.S
create mode 100644 sysdeps/riscv/rvv/memmove.S
create mode 100644 sysdeps/riscv/rvv/memrchr.S
create mode 100644 sysdeps/riscv/rvv/strcat.S
create mode 100644 sysdeps/riscv/rvv/strchr.S
create mode 100644 sysdeps/riscv/rvv/strcmp.S
create mode 100644 sysdeps/riscv/rvv/strcpy.S
create mode 100644 sysdeps/riscv/rvv/strlen.S
create mode 100644 sysdeps/riscv/rvv/strncat.S
create mode 100644 sysdeps/riscv/rvv/strncmp.S
create mode 100644 sysdeps/riscv/rvv/strncpy.S
create mode 100644 sysdeps/riscv/rvv/strnlen.S
create mode 100644 sysdeps/riscv/rvv/strrchr.S
create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memccpy.c
create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memchr.c
create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memcmp.c
create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memcmpeq.c
create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memmove.c
create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memrchr.c
create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strcat.c
create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strchr.c
create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strcmp.c
create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strcpy.c
create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c
create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strncat.c
create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strncmp.c
create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strncpy.c
create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strnlen.c
create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strrchr.c
--
2.47.2
More information about the Libc-alpha
mailing list