if (int LibCallRegs = getLibCallID(MF, MFI.getCalleeSavedInfo()) + 1) {
// Calculate the size of the frame managed by the libcall. The stack
// alignment of these libcalls should be the same as how we set it in
// getABIStackAlignment.
unsigned LibCallFrameSize =
alignTo((STI.getXLen() / 8) * LibCallRegs, getStackAlign());
RVFI->setLibCallStackSize(LibCallFrameSize);
}
This is the calculation used to determine that. Unfortunately the RVE libcalls don’t follow that pattern, they instead are all coalesced into one that always saves all 3 registers, even though stack alignment is such that it could split them up. Both compiler-rt and libgcc are the same here (and compiler-rt does the same for RV64E), but it’s not been formally written down in GitHub - riscv-non-isa/riscv-toolchain-conventions: Documenting the expected behaviour and supported command-line switches for GNU and LLVM based RISC-V toolchains, so I don’t know how much that was intended. GCC itself does know that RVE always saves 3 registers though, so I guess it is ABI at this point.
I saw this when the E save/restore stubs were added and was also confused. While I have written versions with the lower alignments, it’s not clear they’re better because it’s possible most functions will need to save at least three registers anyway.
I will post the patch I have soon, maybe tomorrow.
I’m confused about your claims regarding GCC - the cfi directives seem to match clang from what I can see here: Compiler Explorer - maybe it was fixed in a recent version?
Ok, I think this strikes me as two parts of the same bug in their system - I believe both their libcall implementations and this code should be keyed of the ABI, rather than the ISA.