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.

Reply via email to