Thomas Goodfellow via llvm-dev
2022-Jan-26 08:35 UTC
[llvm-dev] RISC-V runtime support functions
Compiling for RISC-V, clang makes appropriate use of mem*() functions for bulk operations such as initialisation: ******** // test.c int main() { int a[16] = { 0 }; return a[0]; } $ clang test.c -c --target=riscv32 -march=rv32i -mabi=ilp32 $ llvm-objdump --syms test.o test.o: file format elf32-littleriscv SYMBOL TABLE: 00000000 l df *ABS* 00000000 test.c 00000000 g F .text 0000003c main 00000000 *UND* 00000000 memset ******** Unlike integer helper routines such as __divsi3, the mem* functions are not supplied by compiler-rt. I would naively expect them to come from libc. Some questions: (1) Is there a way to have the compiler provide substitutes, e.g. naive built-in implementations? (2) I didn't successfully build llvm-libc for RISC-V, e.g. configuring as: cmake -DLLVM_TARGETS_TO_BUILD='RISCV' -DLLVM_ENABLE_PROJECTS='clang;lld;compiler-rt;libc' /* other options */ built lib/libllvmlibc.a as elf64-x86-64, and specifying as -DLLVM_ENABLE_RUNTIMES="libc" triggered asserts in the 'X86 FP Stackifier' pass while building LLVM. Is there a way to build llvm/libc for RISC-V? (3) If llvm/libc isn't buildable for a RISC-V baremetal target, what is the best way to supply the missing mem* functions? E.g.: (a) are there problems with using the Newlib-based library in riscv-gnu-toolchain for this? (the OS-dependent functions that use ecall instructions won't be supported but hopefully mem*, str*, math.h, etc, all work.) (b) Picolibc (https://keithp.com/picolibc/) looks like another possibility? (c) or just provide (naive) implementations, e.g. textbook implementations in 'C'? -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20220126/2c8cc827/attachment.html>
Jessica Clarke via llvm-dev
2022-Jan-26 13:46 UTC
[llvm-dev] RISC-V runtime support functions
On 26 Jan 2022, at 08:35, Thomas Goodfellow via llvm-dev <llvm-dev at lists.llvm.org> wrote:> > Compiling for RISC-V, clang makes appropriate use of mem*() functions for bulk operations such as initialisation: > > ******** > // test.c > int main() { > int a[16] = { 0 }; > return a[0]; > } > > $ clang test.c -c --target=riscv32 -march=rv32i -mabi=ilp32 > $ llvm-objdump --syms test.o > test.o: file format elf32-littleriscv > > SYMBOL TABLE: > 00000000 l df *ABS* 00000000 test.c > 00000000 g F .text 0000003c main > 00000000 *UND* 00000000 memset > ******** > > Unlike integer helper routines such as __divsi3, the mem* functions are not supplied by compiler-rt. I would naively expect them to come from libc. Some questions: > > (1) Is there a way to have the compiler provide substitutes, e.g. naive built-in implementations?No. If you don’t compile with -ffreestanding then Clang will assume you have a full libc implementation per the C standard. If you compile with -ffreestanding then, like GCC, it will still require memcpy, memset, memmove and memcmp. This is technically wrong but not doing so would lead to extreme code bloat on architectures that don’t have native instructions for those operations.> (2) I didn't successfully build llvm-libc for RISC-V, e.g. configuring as: > > cmake -DLLVM_TARGETS_TO_BUILD='RISCV' -DLLVM_ENABLE_PROJECTS='clang;lld;compiler-rt;libc' /* other options */ > > built lib/libllvmlibc.a as elf64-x86-64, and specifying as -DLLVM_ENABLE_RUNTIMES="libc" triggered asserts in the 'X86 FP Stackifier' pass while building LLVM. Is there a way to build llvm/libc for RISC-V?I don’t know if LLVM libc supports RISC-V, but yes, -DLLVM_ENABLE_PROJECTS will give you a native build of those projects; -DLLVM_ENABLE_RUNTIMES, or building the project separately as its own CMake project pointing at your just-built Clang, is how it would work if it did. Assertion failures in the X86 FP Stackifier pass don’t make much sense though.> (3) If llvm/libc isn't buildable for a RISC-V baremetal target, what is the best way to supply the missing mem* functions? E.g.: > (a) are there problems with using the Newlib-based library in riscv-gnu-toolchain for this? (the OS-dependent functions that use ecall instructions won't be supported but hopefully mem*, str*, math.h, etc, all work.) (b) Picolibc (https://keithp.com/picolibc/) looks like another possibility?Newlib works fine and is the normal thing people use. Never tried picolibc but provided it supports RISC-V there should be no reason why it wouldn’t work.> (c) or just provide (naive) implementations, e.g. textbook implementations in 'C'?Also works fine. Jess