Closed chrysn closed 4 years ago
hm, llvm is built for a subset of nodes, for performance reasons. examples/gcoap is built for nrf52dk (here).
I tried to reproduce this locally, it builds fine with llvm 10, apart from some poweroff not used in the usb code.
Is this on master?
This is on master, yes -- are you on Debian as well? (They enable additional features sometime).
Things do start working once I undef'd MODULE_CORTEXM_FPU. The chip in question (nrf52840) does have an FPU according to its spec.
Drilling down further, I found that makefiles/arch/cortexm.inc.mk does not set any CFLAGS_FPU on llvm -- probably something that was OK for some time when things would then just not the FPU, but now that there's FPU-related assembly in there, this must be coordinated better.
I tried just removing the llvm guard (hoping that whatever it was that LLVM couldn't do back than it learned), and things now build with -mcpu=cortex-m4 -mlittle-endian -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
all the way through.
The comments around the guards suggest Clang does FPU all the time (# clang assumes there is an FPU, no CFLAGS necessary
); possibly that assumption just does not hold any more. Given that even clang 8 (on my system) accepts the additional flags, I don't see immediate harm in removing those conditions. (It'd still be interesting to see why the discrepancy comes from, though.)
This is on master, yes -- are you on Debian as well? (They enable additional features sometime).
I'm on arch, so probably using default llvm flags.
So the minimal test case I came up with is this:
test.c
:
int main() {
__asm__ volatile (
"it eq \n"
"vstmdbeq r0!, {s16-s31} \n" /* save FPU registers if FPU is used */
);
}
$ clang -target arm-none-eabi -mcpu=cortex-m4 -mlittle-endian -mthumb test.c
test.c:4:6: error: instruction requires: fp registers
"vstmdbeq r0!, {s16-s31} \n" /* save FPU registers if FPU is used */
^
<inline asm>:2:1: note: instantiated into assembly here
vstmdbeq r0!, {s16-s31}
^
1 error generated.
$ clang -target arm-none-eabi -mcpu=cortex-m4 -mlittle-endian -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 test.c
[ other errors happening later at linking stage ]
Do those generate the same linking-stage errors at your end?
[kaspar@ng ~/tmp]$ cat tst.c
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: tst.c
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ int main() {
2 │ __asm__ volatile (
3 │ "it eq \n"
4 │ "vstmdbeq r0!, {s16-s31} \n" /* save FPU registers if FPU is used */
5 │ );
6 │ }
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
[kaspar@ng ~/tmp]$ clang -target arm-none-eabi -mcpu=cortex-m4 -mlittle-endian -mthumb tst.c
ld.lld: error: unable to find library -lc
ld.lld: error: unable to find library -lm
ld.lld: error: unable to find library -lclang_rt.builtins-arm.a
clang-10: error: ld.lld command failed with exit code 1 (use -v to see invocation)
[kaspar@ng ~/tmp]$ clang -target arm-none-eabi -mcpu=cortex-m4 -mlittle-endian -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 tst.c
ld.lld: error: unable to find library -lc
ld.lld: error: unable to find library -lm
ld.lld: error: unable to find library -lclang_rt.builtins-arm.a
clang-10: error: ld.lld command failed with exit code 1 (use -v to see invocation)
[kaspar@ng ~/tmp]$ clang --version
clang version 10.0.1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
[kaspar@ng ~/tmp]$
(sorry, using bat instead of cat)
That does sound like you get to the later stage with both versions. (I don't get the very same errors, but the error for the full version at my end is sufficiently close to yours:
clang: error: unable to execute command: Executable "ld.lld" doesn't exist!
clang: error: ld.lld command failed with exit code 1 (use -v to see invocation)
).
So maybe the -v
flag can shed more light -- I get:
In all the argument soup, it stands out that without explicit configuration, my clang 10 goes to soft float mode. If you run clang -target arm-none-eabi -mcpu=cortex-m4 -mlittle-endian -mthumb -mfloat-abi=soft tst.c
, do you run into the same "instruction requires: fp registers" error I do for the implicit case (indicating we have different defaults), or into the "error: invalid float ABI" that's expected if your compiler doesn't know what float-abi=soft means?
I've just given this another test with clang-7 on Debian stretch's backports -- same behavior as with my regular system, clang wants float flags to accept float assembly instructions.
From inspecting Debian sources, there is a patch that does change the default behavior. As that gives us different defaults on different platforms, the best way forward I see is to explicitly pass the flags -- it does not seem that they do any harm when set.
PR to follow.
Description
Builds with nrf52 fail at several places when run with TOOLCHAIN=llvm, both with default clang (version 9 on my machine) and clang-10
Steps to reproduce the issue
Expected results
Builds with LLVM should (be tested to) work just as with GCC.
Versions
Further experimentation
I'm seeing similar results with other boards, eg. nucleo-l496zg (also both with clang implicityly 9 and clang 10, also clang 8).