[RISCV] Guard the alternative static chain register use on ILP32E/LP64E (#142715)

Asserts the use of t3(x28) as the static chain register when branch control flow protection is enabled with ILP32E/LP64E, because such register is not present within the ABI.
This commit is contained in:
Jesse Huang
2025-06-12 02:24:10 +08:00
committed by GitHub
parent 42c82fcc29
commit 806333063f
2 changed files with 19 additions and 8 deletions

View File

@@ -333,15 +333,23 @@ bool llvm::CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT,
unsigned XLen = Subtarget.getXLen();
MVT XLenVT = Subtarget.getXLenVT();
// Static chain parameter must not be passed in normal argument registers,
// so we assign t2/t3 for it as done in GCC's __builtin_call_with_static_chain
bool HasCFBranch =
Subtarget.hasStdExtZicfilp() &&
MF.getFunction().getParent()->getModuleFlag("cf-protection-branch");
// Normal: t2, Branch control flow protection: t3
const auto StaticChainReg = HasCFBranch ? RISCV::X28 : RISCV::X7;
if (ArgFlags.isNest()) {
// Static chain parameter must not be passed in normal argument registers,
// so we assign t2/t3 for it as done in GCC's
// __builtin_call_with_static_chain
bool HasCFBranch =
Subtarget.hasStdExtZicfilp() &&
MF.getFunction().getParent()->getModuleFlag("cf-protection-branch");
// Normal: t2, Branch control flow protection: t3
const auto StaticChainReg = HasCFBranch ? RISCV::X28 : RISCV::X7;
RISCVABI::ABI ABI = Subtarget.getTargetABI();
if (HasCFBranch &&
(ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E))
reportFatalUsageError(
"Nested functions with control flow protection are not "
"usable with ILP32E or LP64E ABI.");
if (MCRegister Reg = State.AllocateReg(StaticChainReg)) {
State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
return false;

View File

@@ -5,6 +5,8 @@
; RUN: | FileCheck -check-prefix=RV64I %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zicfilp -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV64I-ZICFILP %s
; RUN: not llc -mtriple=riscv64 -target-abi=lp64e -mattr=+experimental-zicfilp \
; RUN: -verify-machineinstrs < %s 2>&1 | FileCheck -check-prefix=LP64E-ZICFILP %s
; Tests that the 'nest' parameter attribute causes the relevant parameter to be
; passed in the right register.
@@ -63,6 +65,7 @@ define ptr @nest_caller(ptr %arg) nounwind {
ret ptr %result
}
; LP64E-ZICFILP: LLVM ERROR: Nested functions with control flow protection are not usable with ILP32E or LP64E ABI.
!llvm.module.flags = !{!0}
!0 = !{i32 8, !"cf-protection-branch", i32 1}