RISC-V calling convention implementation in clang: tp and gp registers

Hi,
tp​ and gp​ are two reserved registers in the RISC-V ABI where they both stand for thread pointer and global pointer respectively. The std. mentions that these pointers need to be un-allocatable and user programs should not modify them. They are neither callee saved nor caller saved according to the std ABI.

Calling convention ABI doc: riscv-elf-psabi-doc/riscv-cc.adoc at master · riscv-non-isa/riscv-elf-psabi-doc · GitHub

However, in the clang backend of RISC-V, tp and gp are reserved registers but they are also being set as callee saved registers. This is creating some issues for a platform where the tp​ register is being used as thread pointer.

For eg, when we modify this register through inline assembly or through a global register variable, clang will emit save-restore code in prolog and epilog of the function effectively undoing the change users want to make.

I find this register to be similar to ARM X18 register which is assigned the role of being a reserved platform register [std. also permits it to being used as a temp. register if the platform does not need this register]. In case of X18, it is not set as a callee saved register in the default calling convention and there’s another calling convention made available where X18 is a callee saved register.

I’m looking to know if there was any reason for setting tp and gp as callee saved or if its a bug in clang.

Reproducible example: Compiler Explorer

2 Likes

I played around with gcc and it doesn’t look they are considered callee save registers there. So I think maybe we should remove them from the callee save list in llvm.

WDYT @kito-cheng @jrtc27 @asb

Based on the example in this thread, it sounds like we should change it as you suggest Craig.

Thanks for looking into this. I can take up pushing correction to llvm main

I think this can solve issue at ⚙ D139996 [RISCV] Disable callee-saved register when the register is written by llvm.write_register intrinsic

Thanks! I think @topperc has committed it in [RISCV] Remove gp and tp from callee saved register lists. by topperc · Pull Request #76483 · llvm/llvm-project · GitHub.

2 Likes