This is an archive of the discontinued LLVM Phabricator instance.

[libc] Start to refactor riscv platform abstraction to support both 32 and 64 bits versions
ClosedPublic

Authored by mikhail.ramalho on Apr 20 2023, 5:43 AM.

Details

Summary

This patch is the first in a series of patches to refactor the riscv
abstraction in libc to support both riscv32 and riscv64. This patch
enables the compilation of libc with LLVM_LIBC_FULL_BUILD=OFF and libm
disabled. This patch also fixes the strtol test cases so the tests
enabled by this libc configuration are now passing in riscv32 as well.

We updated the cmake file to match the new riscv32 arch and force
LIBC_TARGET_ARCHITECTURE to be "riscv" whenever we find "riscv32" or
"riscv64". This is required as LIBC_TARGET_ARCHITECTURE is used in the
path for several platform specific implementations.

A int get_except() is also added until to allow the compilation in
riscv32, until we implement the platform specific implementation for
this arch.

Diff Detail

Event Timeline

Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptApr 20 2023, 5:43 AM
mikhail.ramalho requested review of this revision.Apr 20 2023, 5:43 AM

Renamed dirs riscv64 to riscv

Overall LGTM, though are we sure that having the riscv 64 bit and 32 bit targets is the correct path? On other platforms so far we've separated the 32 bit and 64 bit targets.

This is fine. But, can you share the status of what works and what does not on riscv32 and also your riscv32 environment?

Overall LGTM, though are we sure that having the riscv 64 bit and 32 bit targets is the correct path? On other platforms so far we've separated the 32 bit and 64 bit targets.

My guess is that the code will just work... I believe the only change between the two targets is setjmp/longjmp, where the 64 bits version uses fld, ld, sd, fsd, and the 32 bits will need flw, lw, sw, fsw.

This is fine. But, can you share the status of what works and what does not on riscv32 and also your riscv32 environment?

Sure, in the commit message, you mean?

Right now, basic libc should compile, i.e., fullbuild=off and no libm.

For testing, I'm using:

root@qemuriscv32:~# uname -a
Linux qemuriscv32 6.1.20-yocto-standard #1 SMP PREEMPT Sat Mar 18 02:48:04 UTC 2023 riscv32 GNU/Linux

root@qemuriscv32:~# clang -v
clang version 16.0.1 (https://github.com/llvm/llvm-project cd89023f797900e4492da58b7bed36f702120011)
Target: riscv32-poky-linux
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/riscv32-poky-linux/12.2.0
Found candidate GCC installation: /usr/bin/../lib/riscv32-poky-linux/12.2.0
Selected GCC installation: /usr/bin/../lib/riscv32-poky-linux/12.2.0

For development, I'm using ToT clang.

My guess is that the code will just work... I believe the only change between the two targets is setjmp/longjmp, where the 64 bits version uses fld, ld, sd, fsd, and the 32 bits will need flw, lw, sw, fsw.

Are you able to validate your guess with testing?

This is fine. But, can you share the status of what works and what does not on riscv32 and also your riscv32 environment?

Sure, in the commit message, you mean?

Yes, in the commit message at the least.

For testing, I'm using:

root@qemuriscv32:~# uname -a
Linux qemuriscv32 6.1.20-yocto-standard #1 SMP PREEMPT Sat Mar 18 02:48:04 UTC 2023 riscv32 GNU/Linux

Can you start a discourse thread with detailed instructions on how to setup the riscv32 emulator? Or, feel free to send a riscv focused doc patch - we will figure out where and how exactly to land it during the review.

Are you able to validate your guess with testing?

For the current code, yes. I'm currently changing the floating-point code to properly handle UInt<128> and so far it's working properly. I'm not sure about the code when libc_full=ON is enabled but I'm only foreseeing the setjmp/longjmp issue I've mentioned.

I can send a bigger patch when both riscv32/64 are enabled if you fell that's a better approach.

Can you start a discourse thread with detailed instructions on how to setup the riscv32 emulator? Or, feel free to send a riscv focused doc patch - we will figure out where and how exactly to land it during the review.

Sure, I was planning to write a blog post about it too soon.

  • Added details about the current status of the riscv32 port in the commit message
  • Added LIBC_TARGET_ARCH_IS_ANY_RISCV and fix a syscall infinite recursion
mikhail.ramalho edited the summary of this revision. (Show Details)Apr 26 2023, 8:10 AM
mikhail.ramalho edited the summary of this revision. (Show Details)

This change LGTM in general. But, I would like to have instructions on how to test this before I accept it. Couple of reasons:

  1. We want to have an estimate for the public CI.
  2. Since this patch is unifying riscv64 and riscv32, I want to see how much of riscv32 actually works. Things like, if a riscv64 change does not work for riscv32, would we require that the contributor/patch author block on riscv32 changes?

Fixed strtol tests to pass in riscv32

mikhail.ramalho edited the summary of this revision. (Show Details)Apr 26 2023, 1:22 PM
  • Fixed wrong define
  • Rebased

Changed some defines to LIBC_TARGET_ARCH_IS_ANY_RISCV

This change LGTM in general. But, I would like to have instructions on how to test this before I accept it. Couple of reasons:

  1. We want to have an estimate for the public CI.
  2. Since this patch is unifying riscv64 and riscv32, I want to see how much of riscv32 actually works. Things like, if a riscv64 change does not work for riscv32, would we require that the contributor/patch author block on riscv32 changes?

I would like to see answers to the above questions before we can take this patch forward.

evandro removed a subscriber: evandro.May 24 2023, 1:48 PM

This change LGTM in general. But, I would like to have instructions on how to test this before I accept it. Couple of reasons:

  1. We want to have an estimate for the public CI.

Sorry, I didn't understand the question. What do you mean by that?

  1. Since this patch is unifying riscv64 and riscv32, I want to see how much of riscv32 actually works. Things like, if a riscv64 change does not work for riscv32, would we require that the contributor/patch author block on riscv32 changes?

So far most of the changes needed to port the code to rv32 are related to either UInt<128> not playing nice with the rest of the code or the need to use alternative syscalls (usually with the suffix 64). Once the current patches land, all the test cases with LIBC_FULL=OFF will pass.

Except for the assembly in longjmp/setjmp, the rest of the code should just work in rv32.

Every platform we support gets broken occasionally by patches that forget to take it into account. Without buildbots telling us when the platform is broken, then we can't fix it. An example for this would be the arm32 failing to update for several months and our strtol tests breaking on it, leading to this patch: https://reviews.llvm.org/D151935.
For this reason we require anyone adding a new platform to demonstrate their plan for supporting that platform through CI. You can look at the "CI Builders" section on this page for more details: https://libc.llvm.org/porting.html

@sivachandra @michaelrj I'm working with @asb to bring a rv32 buildbot up this week.

I created a script that will copy all the test cases + test data to an rv32 image running on qemu, and then use CMake's -DCROSSCOMPILING flag to run the tests.

On my machine, it takes around 20 min to run ninja check-libc, but since the bots only do ninja libc-integration-tests, ninja libc-api-test, and ninja libc-unit-tests, each run should be faster than that.

May I ask if this addresses your comments? We'll need this patch + D158033 + D150211 to get rv32 compilation working.

If you have a plan for your buildbot then I think we can add RISC-V 32 as a supported platform. I've added some comments on this patch, but since I will be OOO soon I won't be able to give final approval.

libc/src/__support/OSUtil/linux/syscall.h
23

are syscalls exactly the same for RISC-V 32 and 64? If not, is it worthwhile to keep these separate?

libc/test/src/math/exhaustive/CMakeLists.txt
24 ↗(On Diff #548235)

why do these all need atomic?

If you have a plan for your buildbot then I think we can add RISC-V 32 as a supported platform. I've added some comments on this patch, but since I will be OOO soon I won't be able to give final approval.

We should probably have it running by next week, I already submitted the required changes to llvm-zorg. It will be on staging for now, until we are sure that it's working properly.

libc/src/__support/OSUtil/linux/syscall.h
23

Do you mean the syscall numbers? The ones defined in syscall_numbers.h.inc?

If so, they are all guarded by the corresponding #ifdef __NR_*... This riscv/syscall.h file only defines the macros to call the syscalls.

libc/test/src/math/exhaustive/CMakeLists.txt
24 ↗(On Diff #548235)

They were failing with a missing atomic dependency when using stdout, I'll re-run the tests without it now that we have a new interface for it.

  • Make unit test static
  • Fix some comments
  • Rebased

@sivachandra @michaelrj the rv32 buildbot is up on staging now: https://lab.llvm.org/staging/#/console

I believe this addresses the last of your comments for this PR.

michaelrj accepted this revision.Sep 25 2023, 10:13 AM

LGTM, thank you for finishing this!

This revision is now accepted and ready to land.Sep 25 2023, 10:13 AM
libc/src/__support/FPUtil/riscv/sqrt.h