[llvm] [RFC][BPF] Do atomic_fetch_*() pattern matching with memory ordering (PR #107343)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 5 16:46:06 PDT 2024
eddyz87 wrote:
So, basically we want to generate `lock *(u64 *)(rX + ...) += rY` for `__c11_atomic_fetch_and(..., memory_order_relaxed)` and `rX = atomic_fetch_add(...)` for everything else.
`memory_order_relaxed` corresponds to [monotonic](https://llvm.org/docs/Atomics.html#monotonic) LLVM IR ordering.
And basing on the referred mailing list discussion, this is done to allow ARM jit to generate [`LDADD`](https://developer.arm.com/documentation/ddi0602/2024-06/Base-Instructions/LDADD--LDADDA--LDADDAL--LDADDL--Atomic-add-on-word-or-doubleword-in-memory-) instruction (w/o `L` or `A` or `AL` suffixes) for this C interface (which it currently does for `lock ...` instructions).
I was unable to figure out from the ARM documentation whether `LDADD` is [monotonic](https://llvm.org/docs/Atomics.html#monotonic) or [unordered](https://llvm.org/docs/Atomics.html#unordered). However, the test below shows that at-least we are on the same page with LLVM ARM backend:
```c
$ cat test2.c
void f1(_Atomic long *i) { __c11_atomic_fetch_add(i, 10, __ATOMIC_RELAXED); }
void f2(_Atomic long *i) { __c11_atomic_fetch_add(i, 10, __ATOMIC_CONSUME); }
void f3(_Atomic long *i) { __c11_atomic_fetch_add(i, 10, __ATOMIC_ACQUIRE); }
void f4(_Atomic long *i) { __c11_atomic_fetch_add(i, 10, __ATOMIC_RELEASE); }
void f5(_Atomic long *i) { __c11_atomic_fetch_add(i, 10, __ATOMIC_ACQ_REL); }
void f6(_Atomic long *i) { __c11_atomic_fetch_add(i, 10, __ATOMIC_SEQ_CST); }
```
```bash
$ clang --target=aarch64 -march=armv8.1-a -O2 test2.c -c -o - | llvm-objdump -Sdr -
```
```asm
<stdin>: file format elf64-littleaarch64
Disassembly of section .text:
0000000000000000 <f1>:
0: 52800148 mov w8, #0xa // =10
4: f8280008 ldadd x8, x8, [x0]
8: d65f03c0 ret
000000000000000c <f2>:
c: 52800148 mov w8, #0xa // =10
10: f8a80008 ldadda x8, x8, [x0]
14: d65f03c0 ret
0000000000000018 <f3>:
18: 52800148 mov w8, #0xa // =10
1c: f8a80008 ldadda x8, x8, [x0]
20: d65f03c0 ret
0000000000000024 <f4>:
24: 52800148 mov w8, #0xa // =10
28: f8680008 ldaddl x8, x8, [x0]
2c: d65f03c0 ret
0000000000000030 <f5>:
30: 52800148 mov w8, #0xa // =10
34: f8e80008 ldaddal x8, x8, [x0]
38: d65f03c0 ret
000000000000003c <f6>:
3c: 52800148 mov w8, #0xa // =10
40: f8e80008 ldaddal x8, x8, [x0]
44: d65f03c0 ret
```
So, I think we are good.
Question: should BPF backend report and error if `__ATOMIC_{CONSUME,ACQUIRE,RELEASE,ACQ_REL}` is used?
LLVM documentation [allows this](https://llvm.org/docs/Atomics.html#unordered).
https://github.com/llvm/llvm-project/pull/107343
More information about the llvm-commits
mailing list