-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Open
Description
Some of our kernel developers pointed out an odd instruction sequence emited by clang. We're not sure why this strange branch sequence appears, since its basically a NOP.
Godbolt: https://godbolt.org/z/T77qWvxW5
#include <atomic>
#include <stdlib.h>
bool cmpxchg(std::atomic<uint32_t>& a, uint32_t& expected, uint32_t desired) {
return a.compare_exchange_strong(expected, desired, std::memory_order_acq_rel);
}cmpxchg(std::atomic<unsigned int>&, unsigned int&, unsigned int):
ldr w9, [x1]
.LBB0_1:
ldaxr w8, [x0]
cmp w8, w9
b.ne .LBB0_4
stlxr w10, w2, [x0]
cbnz w10, .LBB0_1
mov w0, #1 // <-- move 1 into W)
tbz w0, #0, .LBB0_5 // <-- branch if the 0th bit is zero (always false)
b .LBB0_6 // Always taken
.LBB0_4:
mov w0, wzr
clrex
tbnz wzr, #0, .LBB0_6
.LBB0_5:
str w8, [x1]
.LBB0_6:
retDoes anyone know why this is emitted this way? We could find no reason that we'd want such a lowering.