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

            Bug ID: 86005
           Summary: [RISCV] Invalid lowering of atomics for -march=rv32i /
                    -march=rv64i
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: translation
          Assignee: unassigned at gcc dot gnu.org
          Reporter: asb at lowrisc dot org
  Target Milestone: ---

When targeting -march=rv32i or -march=rv64i (i.e. a RISC-V target without the A
extension), GCC will produce a fence-based mapping for atomic load and store
while calling the __atomic_* libcalls for other operations. As documented here
<https://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary> this is not legal. As stated
there and in the equivalent LLVM documentation
<https://llvm.org/docs/Atomics.html#atomics-and-codegen> lock-based library
calls and lock-free instructions should not be intermixed for the same object.

Below is a representative example, where I believe a call to __atomic_load_4
should be generated.

$ cat foo.c
int atomic(int *i) {
  int j = __atomic_add_fetch(i, 1, __ATOMIC_SEQ_CST);
  int k;
  __atomic_load(i, &k, __ATOMIC_SEQ_CST);
  return j+k;
}

$ ./riscv32-unknown-elf-gcc -march=rv32i foo.c -O1 -S -o -
        .file   "foo.c"
        .option nopic
        .text
        .align  2
        .globl  atomic
        .type   atomic, @function
atomic:
        addi    sp,sp,-16
        sw      ra,12(sp)
        sw      s0,8(sp)
        mv      s0,a0
        li      a2,5
        li      a1,1
        call    __atomic_fetch_add_4
        addi    a0,a0,1
        fence   iorw,iorw
        lw      a5,0(s0)
        fence   iorw,iorw
        add     a0,a5,a0
        lw      ra,12(sp)
        lw      s0,8(sp)
        addi    sp,sp,16
        jr      ra
        .size   atomic, .-atomic
        .ident  "GCC: (GNU) 9.0.0 20180530 (experimental)"

Reply via email to