Issue 164194
Summary RISCV fence and load order broken when function inlined twice
Labels new issue
Assignees
Reporter macdice
    ```
struct PgAioHandle {
    char x;
    int y;
};

static inline bool
f(struct PgAioHandle *ioh, int y, char *x)
{
 *x = ioh->x;
    __atomic_thread_fence(__ATOMIC_ACQUIRE);
    if (ioh->y != y)
      return false;
    return true;
}

bool
g(struct PgAioHandle *ioh, int y)
{
    char x;
    if (!f(ioh, y, &x))
        return false;
    if (!f(ioh, y, &x))
        return false;
    return x != 0;
}
```

If f() is inlined just once (ie commend out the second call), then we load ->x before ->y with a fence as expected:

```
        lbu a2, 0(a0)
        fence   r, rw
        lw      a0, 4(a0)
```

If f() is inlined twice, then we get this:

```
        fence   r, rw
        lw a2, 4(a0)
        bne     a2, a1, .LBB0_3
        fence   r, rw
 lw      a2, 4(a0)
        bne     a2, a1, .LBB0_3
        lbu     a0, 0(a0)
```

The lbu of ->x is on the wrong side of the fence, right? Happens with all Clang versions on godbolt with -O1 and above, but doesn't happen with GCC.  (This is minimized from src/backend/storage/aio/aio.c in PostgreSQL.)

https://godbolt.org/z/En4xKcfWz

_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to