[BPF] Live monotonic atomicrmw lowers to non-FETCH and returns wrong value
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
## Description
The BPF backend compiles a monotonic `atomicrmw` with a live result to a non-FETCH instruction. The memory update works correctly, but the program returns the input operand (e.g. the addend) instead of the old memory value.
Here is an example:
```c
x = 100;
old = __atomic_fetch_add(&x, 7, __ATOMIC_RELAXED);
```
Clang 22.1.8 produces x = 107 and old = 7; the expected result is x = 107 and old = 100.
## Reproducer
[Compiler Explorer reproducer](https://godbolt.org/z/Gsje6xbjn)
Actual:
```c
r0 = 7
lock *(u64 *)(r1 + 0) += r0
exit
```
Expected:
```c
r0 = 7
r0 = atomic_fetch_add((u64 *)(r1 + 0), r0)
exit
```
## Runtime PoC
the test BPF program: Initializes x = 100, executes the atomic operation once, and reads the result from a map.
Variant | Final x | Returned old value
-- | -- | --
Clang 22.1.8, relaxed, live result | 107 | 7
Clang 18.1.3, relaxed, live result | 107 | 100
Clang 22.1.8, acquire, live result | 107 | 100
The failure was reproduced for i32 and i64 with -mcpu=v3 and -mcpu=v4. All programs were accepted by the Linux verifier.
## Notes
This conflicts with the behavior described in [#107343](https://github.com/llvm/llvm-project/pull/107343):
"For monotonic ordering, locked insns are generated if return value is not used. Otherwise, atomic_fetch_() insns are used."
Contributor guide
Research direction
Start with the Compiler Explorer reproducer and runtime PoC, then trace the BPF backend's lowering of a monotonic atomicrmw when its result is live. Compare the generated non-FETCH and atomic_fetch_add instructions for i32 and i64; done means the update remains correct and the returned value is the old memory value, including for relaxed ordering.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100