cmake: kconfig: llvm: riscv: Add baseline clang/llvm support for RISC-V #68259
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Overview
This patch aims to establish a baseline level of support for building with clang/LLVM when targeting RISC-V. Previously, a few minor things were missing that prevented building:
With these two things resolved, a decent number of the tests that support the qemu_riscv32/64 platforms are passing. However, there are still some lingering failures and misc. warnings that I hope to resolve in subsequent PRs--see the "Testing" and "Follow-up work" sections for details. I left these as future work given the number of different issues, but I can slowly work on them and include the fixes here if that would be preferable!
Testing
This patch was tested by enabling 'llvm' in the qemu_riscv32.yaml and qemu_riscv64.yaml files and running the tests for these boards with clang + lld as well as clang + GNU ld. I am using a version of clang/llvm built at llvm/llvm-project@f7669ba (from 1/23/2024, so fairly recent).
Tests were run with the following commands. Please note that
-W
was specified as there are some unexpected warnings appearing currently.west twister -W -p qemu_riscv[32/64] -x=CONFIG_LLVM_USE_LD=y -x=CONFIG_COMPILER_RT_RTLIB=y
west twister -W -p qemu_riscv[32/64] -x=CONFIG_LLVM_USE_LLD=y -x=CONFIG_COMPILER_RT_RTLIB=y
Test summaries are shown below:
INFO - 469 of 2463 test configurations passed (95.71%), 4 failed, 17 errored, 1973 skipped with 0 warnings in 1673.90 seconds
INFO - 471 of 2463 test configurations passed (96.52%), 12 failed, 5 errored, 1975 skipped with 0 warnings in 1685.06 seconds
INFO - 469 of 2463 test configurations passed (95.71%), 4 failed, 17 errored, 1973 skipped with 0 warnings in 1740.49 seconds
INFO - 325 of 2463 test configurations passed (66.60%), 1 failed, 162 errored, 1975 skipped with 0 warnings in 1391.14 seconds
Notable test failures that I'm aware of:
unsupported argument 'medany' to option ... for target <default target>
. I think the build commands for the external library in the test are not setting--target
appropriately.error: .option pop with no .option push
. This is an issue with clang--it does not handle having .push and .pop specified in separate inline-asm statements well.&initialized_by_function not equal to &initialized_by_macro
. I think this might be an issue with clang--I'm still investigating this though.error: unknown type name 'ssize_t'; did you mean 'size_t'?
. My understanding is that for these tests Zephyr's toolchain is invoked with--specs=picolibc.specs
which helps to find the right definition ofssize_t
. Clang doesn't support--specs
, so I need to investigate to see how best to support these cases.Follow-up work
In addition to the test failures above, there are a few other issues with the Zephyr/LLVM/RISC-V combo I'm aware of that I'd like to resolve in later PRs:
/workdir/zephyr/drivers/timer/riscv_machine_timer.c:187:47: warning: implicit conversion from 'unsigned long' to 'int32_t' (aka 'int') changes value from 92233720368547 to -702313053 [-Wconstant-conversion]
/workdir/zephyr/include/zephyr/arch/riscv/arch_inlines.h:17:9: warning: 'register' storage class specifier is deprecated and incompatible with C++17
Questions
include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_riscv.cmake)
incmake/compiler/clang/target.cmake
is that it requires a version of LLVM that is able to handle the separate zicsr and zifencei extensions. This was only very recently implemented in LLVM, however (llvm/llvm-project@22e199e). So, effectively this would require an LLVM version >= 17.x. Would it be better to version gate adding zicsr and zifencei to the -march string for incompatible LLVM versions? I think doing so should be correct from a RISC-V/LLVM standpoint, but I'm not sure what makes sense from Zephyr's standpoint.qemu_riscv[32/64].yaml
config files to make testing easier for others? I didn't mark llvm as supported due to the number of failures, but I'd like to enable this long-term if that would be ok.