Closed
Description
Noticed while working on rust-lang/rust#114034. When the replacement value is known to be zero then we should lower to an amoand
instead of a LL/SC loop.
IR
define zeroext i8 @swap_zero(ptr %0) {
%2 = atomicrmw xchg ptr %0, i8 0 monotonic
ret i8 %2
}
Current output
swap_zero: # @swap_zero
andi a1, a0, -4
slli a0, a0, 3
li a2, 255
sllw a2, a2, a0
.LBB0_1: # =>This Inner Loop Header: Depth=1
lr.w a3, (a1)
li a4, 0
xor a4, a3, a4
and a4, a4, a2
xor a4, a3, a4
sc.w a4, a4, (a1)
bnez a4, .LBB0_1
srlw a0, a3, a0
andi a0, a0, 255
ret
Ideal output
swap_zero: # @swap_zero
andi a1, a0, -4
slli a0, a0, 3
li a2, 255
sllw a2, a2, a0
not a2, a2
amoand a1, a2, (a1)
srlw a0, a1, a0
andi a0, a0, 255
ret