https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108031

            Bug ID: 108031
           Summary: riscv: Access of members of a global structure is not
                    optimized in atomic operations
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: sebastian.hu...@embedded-brains.de
  Target Milestone: ---

Consider the following test code:

struct s {
  int a;
  int b;
};

struct s s;

int f(void)
{
  return __atomic_fetch_add(&s.a, 1, 0) + __atomic_fetch_add(&s.b, 1, 0);
}

Using gcc -O2 -S -o - test.c yields:

f:
        lui     a5,%hi(s)
        li      a4,1
        addi    a5,a5,%lo(s)
        amoadd.w a0,a4,0(a5)
        lui     a5,%hi(s+4) <-- this should be: addi a5, a5, 4
        addi    a5,a5,%lo(s+4) <-- this should be removed
        amoadd.w a3,a4,0(a5)
        add     a0,a0,a3
        ret

This seems to be a backend issue since on arm we have for example (gcc
-march=armv7-a -O2 -S -o - test.c):
f:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        movw    r3, #:lower16:.LANCHOR0
        movt    r3, #:upper16:.LANCHOR0
.L2:
        ldrex   r0, [r3]
        add     r2, r0, #1
        strex   r1, r2, [r3]
        cmp     r1, #0
        bne     .L2
        add     r3, r3, #4
.L3:
        ldrex   r2, [r3]
        add     r1, r2, #1
        strex   ip, r1, [r3]
        cmp     ip, #0
        bne     .L3
        add     r0, r0, r2
        bx      lr

clang produces (clang -O2 -S -o - test.c --target=riscv32):

f:
        lui     a0, %hi(s)
        addi    a0, a0, %lo(s)
        li      a1, 1
        amoadd.w        a2, a1, (a0)
        addi    a0, a0, 4
        amoadd.w        a0, a1, (a0)
        add     a0, a0, a2
        ret

Reply via email to