Issue 141488
Summary `cmpxchg weak` generates re-try loop on RISC-V
Labels new issue
Assignees
Reporter newpavlov
    I have the following Rust code ([godbolt](https://rust.godbolt.org/z/KPMsnaEjc)):
```rust
use core::sync::atomic::{AtomicU32, Ordering::{AcqRel, Relaxed}};

pub fn cmpx(a0: &AtomicU32, a1: u32, a2: u32) -> bool {
 a0.compare_exchange_weak(a1, a2, AcqRel, Relaxed).is_ok()
}
```

It lowers to the following LLVM IR:
```llvm
; Function Attrs: mustprogress nofree norecurse nounwind nonlazybind willreturn memory(argmem: readwrite) uwtable
define noundef zeroext i1 @cmpx(ptr nocapture noundef nonnull align 4 %a0, i32 noundef %a1, i32 noundef %a2) unnamed_addr #0 {
start:
  %0 = cmpxchg weak ptr %a0, i32 %a1, i32 %a2 acq_rel monotonic, align 4
  %1 = extractvalue { i32, i1 } %0, 1
  ret i1 %1
}
```
Which in turn gets compiled to the following RISC-V assembly:
```
cmpx:
.LBB0_1:
 lr.w.aq a3, (a0)
        bne     a3, a1, .LBB0_3
        sc.w.rl a4, a2, (a0)
        bnez    a4, .LBB0_1
.LBB0_3:
        xor     a1, a1, a3
 seqz    a0, a1
        ret
```
We can see that LLVM has generated re-try loop despite the fact that weak compare exchange explicitly allows spurious failures (after all, it's the reason why it was introduced). It means that replacing `compare_exchange_weak` with `compare_exchange` results in the same assembly, thus rendering the "weak" variant effectively useless!

Potentially relevant issue: #37521
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to