https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120001
Bug ID: 120001
Summary: On RISC-V with -O2 and -O3 __sync_or_and_fetch in a
loop renders as an endless loop and multiple amoor
Product: gcc
Version: 15.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: vincenzo.romano at gmail dot com
Target Milestone: ---
This code:
#define LOCK_BIT ((unsigned long)(1ul<<(8*sizeof(long)-1)))
void lock_hold(long* lock) {
while(__sync_or_and_fetch(lock,LOCK_BIT) < 0);
__sync_synchronize();
}
with -O2 and -O3 renders as:
lock_hold:
li a5,-1
slli a5,a5,63
.L2:
amoor.d.aqrl a4,a5,0(a0)
amoor.d.aqrl a4,a5,0(a0)
j .L2
(Please also note the double amoor instruction).
Similarly, with -Os it renders as:
lock_hold:
li a5,-1
slli a5,a5,63
.L2:
amoor.d.aqrl a4,a5,0(a0)
j .L2
(Please also note the single amoor instruction).
Instead, with -O1 I get more reasonably:
lock_hold:
li a5,-1
slli a5,a5,63
.L2:
amoor.d.aqrl a4,a5,0(a0)
or a5,a5,a4
blt a5,zero,.L2
fence rw,rw
ret
With -O0 I get something similar to the code generated with -O1.