[PATCH v1 2/4] riscv: Add RVV implementations for mem* routines
Petr Penzin
ppenzin@oss.tenstorrent.com
Wed Oct 8 02:58:02 GMT 2025
Hi,
I have a question about zero length checks. First post here, apologies
in advance if I mess up the formatting of the email.
On Tue Sep 23 11:23:10 GMT 2025 Yao Zihong <zihong.plct@isrc.iscas.ac.cn> wrote:
>
> diff --git a/sysdeps/riscv/multiarch/memcpy_vector.S b/sysdeps/riscv/multiarch/memcpy_vector.S
> new file mode 100644
> index 0000000000..e86e41d42b
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/memcpy_vector.S
> @@ -0,0 +1,46 @@
> +/* RVV versions memcpy. RISC-V version.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <sysdep.h>
> +#include <sys/asm.h>
> +
> +#define dst a0
> +#define src a1
> +#define num a2
> +
> +#define ivl a3
> +#define dst_ptr a4
> +
> +#define ELEM_LMUL_SETTING m8
> +#define vdata v0
> +
> +ENTRY (__memcpy_vector)
Should there be a zero length (num/a2) here? In a previously proposed
patch there was a zero length check that performed `beq a2, zero,
L(ret)`, but it was removed in
https://sourceware.org/pipermail/libc-alpha/2025-January/164041.html
The motivation is that zero length check add special handling for
uncommon case. While it is uncommon, use of zero length in vsetvli
would override ta and ma bits (as vstart>=vl requires all elements to
be unchanged, including agnostic ones). Since agnostic mode is an
optimization on out of order implementations I worry it would make
zero memcopy slower on some of them. Generally zero loads/stores
should be NOPs, but depending on how element handling is implemented
it might lead to rematerialization of some elements that were not
needed in agnostic mode.
> + mv dst_ptr, dst
> +L(loop):
> + vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma
> +
> + vle8.v vdata, (src)
> + sub num, num, ivl
> + add src, src, ivl
> + vse8.v vdata, (dst_ptr)
> + add dst_ptr, dst_ptr, ivl
> +
> + bnez num, L(loop)
> +
> + ret
> +END (__memcpy_vector)
> diff --git a/sysdeps/riscv/multiarch/memmove_vector.S b/sysdeps/riscv/multiarch/memmove_vector.S
> new file mode 100644
> index 0000000000..b4f44fb27d
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/memmove_vector.S
> @@ -0,0 +1,66 @@
> +/* RVV versions memmove. RISC-V version.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <sysdep.h>
> +#include <sys/asm.h>
> +
> +#define dst a0
> +#define src a1
> +#define num a2
> +
> +#define ivl a3
> +#define dst_ptr a4
> +#define src_backward_ptr a5
> +#define dst_backward_ptr a6
> +
> +#define ELEM_LMUL_SETTING m8
> +#define vdata v0
> +
> +ENTRY (__memmove_vector)
> + mv dst_ptr, dst
> +
> + /* If src is equal or after dst, all data in src will be loaded before
> + overwrited for the overlapping case. We could use faster `forward-copy`. */
> + bgeu src, dst, L(forward_copy_loop)
> + add src_backward_ptr, src, num
> + add dst_backward_ptr, dst, num
> + /* If dst inside source data range, we need to use `backward_copy_loop` to
> + handle the overlapping issue. */
> + bltu dst, src_backward_ptr, L(backward_copy_loop)
> +L(forward_copy_loop):
> + vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma
> +
> + vle8.v vdata, (src)
> + sub num, num, ivl
> + add src, src, ivl
> + vse8.v vdata, (dst_ptr)
> + add dst_ptr, dst_ptr, ivl
> +
> + bnez num, L(forward_copy_loop)
> + ret
> +L(backward_copy_loop):
> + vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma
> +
> + sub src_backward_ptr, src_backward_ptr, ivl
> + vle8.v vdata, (src_backward_ptr)
> + sub num, num, ivl
> + sub dst_backward_ptr, dst_backward_ptr, ivl
> + vse8.v vdata, (dst_backward_ptr)
> + bnez num, L(backward_copy_loop)
> + ret
> +END (__memmove_vector)
> diff --git a/sysdeps/riscv/multiarch/memset_vector.S b/sysdeps/riscv/multiarch/memset_vector.S
> new file mode 100644
> index 0000000000..d66ea6dc0a
> --- /dev/null
> +++ b/sysdeps/riscv/multiarch/memset_vector.S
> @@ -0,0 +1,45 @@
> +/* RVV versions memset. RISC-V version.
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <sysdep.h>
> +#include <sys/asm.h>
> +
> +#define dst a0
> +#define value a1
> +#define num a2
> +
> +#define ivl a3
> +#define dst_ptr a5
> +
> +#define ELEM_LMUL_SETTING m8
> +#define vdata v0
> +
> +ENTRY (__memset_vector)
> + mv dst_ptr, dst
> +
> + vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma
> + vmv.v.x vdata, value
> +L(loop):
> + vse8.v vdata, (dst_ptr)
> + sub num, num, ivl
> + add dst_ptr, dst_ptr, ivl
> + vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma
> + bnez num, L(loop)
> +
> + ret
> +END (__memset_vector)
> --
> 2.47.2
More information about the Libc-alpha
mailing list