Re: [PATCH 1/6] riscv: add vectorized memccpy

Kito Cheng <[email protected]> Fri, 22 May 2026 16:50:27 +0800
Newsgroups gmane.comp.lib.newlib
Message-ID <CA+yXCZCdvpna3pV9Anvz4HT+=rfCoJ9Y39LU9XXXVfG3y9QFmg@mail.gmail.com>
Kito Cheng <[email protected]> =E6=96=BC 2026=E5=B9=B45=E6=9C=8822=E6=97=
=A5=E9=80=B1=E4=BA=94 =E4=B8=8B=E5=8D=884:36=E5=AF=AB=E9=81=93=EF=BC=9A
>
> Pincheng Wang <[email protected]> =E6=96=BC 2026=E5=B9=B45=
=E6=9C=8813=E6=97=A5=E9=80=B1=E4=B8=89 =E4=B8=8B=E5=8D=8811:39=E5=AF=AB=E9=
=81=93=EF=BC=9A
> >
> > The vector implementation uses m8 register grouping and processes data =
in
> > vector-length chunks, providing significant performance improvements on
> > RVV-capable hardware.  Use conditional compilation to fall back to the
> > generic implementation when __riscv_vector is not available, maintainin=
g
> > compatibility with non-vector RISC-V systems.
> >
> > Signed-off-by: Pincheng Wang <[email protected]>
> > ---
> >  newlib/libc/machine/riscv/Makefile.inc  | 18 ++++++++++--
> >  newlib/libc/machine/riscv/memccpy-asm.S | 39 +++++++++++++++++++++++++
> >  newlib/libc/machine/riscv/memccpy.c     |  5 ++++
> >  3 files changed, 60 insertions(+), 2 deletions(-)
> >  create mode 100644 newlib/libc/machine/riscv/memccpy-asm.S
> >  create mode 100644 newlib/libc/machine/riscv/memccpy.c
> >
> > diff --git a/newlib/libc/machine/riscv/Makefile.inc b/newlib/libc/machi=
ne/riscv/Makefile.inc
> > index 3cc6e198f..676608aa5 100644
> > --- a/newlib/libc/machine/riscv/Makefile.inc
> > +++ b/newlib/libc/machine/riscv/Makefile.inc
> > @@ -1,3 +1,17 @@
> >  libc_a_SOURCES +=3D \
> > -       %D%/memmove-asm.S %D%/memmove.c %D%/memset.S %D%/memcpy-asm.S %=
D%/memcpy.c %D%/strlen.c \
> > -       %D%/strcpy.c %D%/stpcpy.c %D%/strcmp.S %D%/memchr.c %D%/memrchr=
.c %D%/setjmp.S %D%/ieeefp.c %D%/ffs.c
> > +        %D%/ffs.c \
> > +        %D%/ieeefp.c \
> > +        %D%/memccpy-asm.S \
> > +        %D%/memccpy.c \
> > +        %D%/memchr.c \
> > +        %D%/memcpy-asm.S \
> > +        %D%/memcpy.c \
> > +        %D%/memmove-asm.S \
> > +        %D%/memmove.c \
> > +        %D%/memrchr.c \
> > +        %D%/memset.S \
> > +        %D%/setjmp.S \
> > +        %D%/stpcpy.c \
> > +        %D%/strcmp.S \
> > +        %D%/strcpy.c \
> > +        %D%/strlen.c
> > diff --git a/newlib/libc/machine/riscv/memccpy-asm.S b/newlib/libc/mach=
ine/riscv/memccpy-asm.S
> > new file mode 100644
> > index 000000000..3c33a8ae0
> > --- /dev/null
> > +++ b/newlib/libc/machine/riscv/memccpy-asm.S
> > @@ -0,0 +1,39 @@
> > +#if defined(__riscv_vector) && !defined(__OPTIMIZE_SIZE__) && !defined=
(PREFER_SIZE_OVER_SPEED)
> > +.text
> > +.option push
> > +.option arch, +zve32x
>
> ^^^ BTW we don't really option push option arch here since we already
> guarded with __riscv_vector, that already guarantee we will have
> zve32x anyway.
>
> > +.global memccpy
> > +.type memccpy, @function
> > +memccpy:
> > +#if __riscv_landing_pad
> > +  lpad 0
> > +#endif
> > +  beqz a3, .Lnot_found
> > +  andi a2, a2, 0xff
> > +  mv a5, a0
> > +.Lloop:
> > +  vsetvli zero, a3, e8, m8, ta, ma
> > +  vle8ff.v v0, (a1)
>
> For all vle8ff, I would like to prevent it to use m8 as possible since
> it did really read vlmax elements if does not hit any fault, and that
> could lead very poor performance with small input on large VLEN
> machine.
>
> So here is two possible direction here:
> 1) Just use m1
> 2) Use complicate way to increase the LMUL each time, e.g. start from
> mf2, then switch to m1, then m2, then m4...until m8.

Wait, I realized it did have specify VL unlike strcmp, so withdraw
this comment :)