[clang] [llvm] [RISC-V] Add CSR read/write builtins (PR #85091)

Nemanja Ivanovic via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 14 10:56:39 PDT 2024


nemanjai wrote:

> > > I have always been unconvinced that these are a good idea to have / add significant value over using inline assembly. IIRC Arm has them but nobody uses them?

... 
> If it’s not a constant integer for inline assembly then how would it magically be a constant integer for an intrinsic? The IR’s going to be the same with an alloca/store/load, no?

To be completely clear with the use case:
```
$ cat csrread.c
// An obvious way a library writer tries to provide a
// convenience function for reading CSR's.
#ifdef _ASM
static unsigned __attribute__((always_inline)) read_csr(const unsigned CSR) {
  unsigned Ret;
  __asm__ volatile("csrr %0, %1" : "=r"(Ret) : "I"(CSR));
  return Ret;
}
#else
#define read_csr __builtin_riscv_csrr
#endif

// Use the convenience function.
unsigned someFunc() {
  return read_csr(0x300);
}

$ clang csrread.c -S --target=riscv32 -D_ASM -O1 && echo Success # No error checking for no Zicsr but it compiles
Success

$ clang csrread.c -S --target=riscv32 -D_ASM && echo Success # Does not compile at -O0
csrread.c:6:20: error: constraint 'I' expects an integer constant expression
    6 |   __asm__ volatile("csrr %0, %1" : "=r"(Ret) : "I"(CSR));

$ clang csrread.c -S --target=riscv32 -O1 && echo Success # The builtin provides a nice error message for no Zicsr
csrread.c:15:10: error: builtin requires at least one of the following extensions: 'Zicsr'
   15 |   return read_csr(0x300);

$ clang csrread.c -S --target=riscv32 -march=rv32i_zicsr && echo Success # The builtin compiles fine at -O0
Success

```

In my view, the builtin solution is superior from a usability perspective.

https://github.com/llvm/llvm-project/pull/85091


More information about the cfe-commits mailing list