Open
Description
Our firmware teams have been looking into evaluating clang for their products.
They recently reported one difference between Clang and GCC for armv6m related to inline atomic vs libcall.
$ cat atomic_load.c
typedef int atomic_t;
typedef atomic_t atomic_val_t;
atomic_val_t atomic_get(const atomic_t *target)
{
return __atomic_load_n(target, __ATOMIC_SEQ_CST);
}
GCC generated code:
$ arm-none-eabi-gcc -o atomic_load_cb.o atomic_load.c -c -O1 -march=armv6-m
00000000 <atomic_get>:
0: bf f3 5b 8f dmb ish
4: 00 68 ldr r0, [r0]
6: bf f3 5b 8f dmb ish
a: 70 47 bx lr
Clang generated code:
$ clang --target=arm-none-eabi -o atomic_load_cb.o atomic_load.c -c
-O1 -march=armv6-m
00000000 <atomic_get>:
0: 80 b5 push {r7, lr}
2: 00 af add r7, sp, #0
4: 05 21 movs r1, #5
6: ff f7 fe ff bl 0x6 <atomic_get+0x6> @ imm = #-4
00000006: R_ARM_THM_CALL __atomic_load_4 // call instead of a load
a: 80 bd pop {r7, pc}
No libcall is generated for armv7-m.
This difference is coming from following LLVM code:
https://github.com/llvm/llvm-project/blob/main/clang/lib/Basic/Targets/ARM.cpp#L138
bool ShouldUseInlineAtomic =
(ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
(ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
Is it correct to restrict it for thumb >=7 (v6-m IIUC is thumb2 only)?