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