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.