Skip to content

clang vs gcc difference in armv6m vs armv7m inline atomic codegen #58603

Open
@m-gupta

Description

@m-gupta

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)?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions