From 20866709d984cc17a9aa8fd9438c923c1c201aa7 Mon Sep 17 00:00:00 2001 From: Jesse Huang Date: Tue, 3 Jun 2025 21:55:37 -0700 Subject: [PATCH 1/7] [RISCV] Guard the alternative static chain register use on RV32E --- llvm/lib/Target/RISCV/RISCVCallingConv.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp index e0d1fb2facc87..3b609adcf8c09 100644 --- a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp +++ b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp @@ -338,6 +338,10 @@ bool llvm::CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT, bool HasCFBranch = Subtarget.hasStdExtZicfilp() && MF.getFunction().getParent()->getModuleFlag("cf-protection-branch"); + if (HasCFBranch && (Subtarget.isRV32() && Subtarget.hasStdExtE())) + reportFatalUsageError( + "Alternative static chain register is not supported on RV32E"); + // Normal: t2, Branch control flow protection: t3 const auto StaticChainReg = HasCFBranch ? RISCV::X28 : RISCV::X7; From 8e410def9ae4daeb5175fc3f8ca1338edc281495 Mon Sep 17 00:00:00 2001 From: Jesse Huang Date: Wed, 4 Jun 2025 00:57:46 -0700 Subject: [PATCH 2/7] Addressed comments --- llvm/lib/Target/RISCV/RISCVCallingConv.cpp | 27 ++++++++++++---------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp index 3b609adcf8c09..d1c31601f2871 100644 --- a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp +++ b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp @@ -333,19 +333,22 @@ 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"); - if (HasCFBranch && (Subtarget.isRV32() && Subtarget.hasStdExtE())) - reportFatalUsageError( - "Alternative static chain register is not supported on RV32E"); - - // 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( + "Alternative static chain register t3 is not usable with EABI."); if (MCRegister Reg = State.AllocateReg(StaticChainReg)) { State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); return false; From 01b79860204db3127e8ce0fc3fb234dfab9cff4f Mon Sep 17 00:00:00 2001 From: Jesse Huang Date: Wed, 4 Jun 2025 16:37:28 +0800 Subject: [PATCH 3/7] Update llvm/lib/Target/RISCV/RISCVCallingConv.cpp Co-authored-by: Kito Cheng --- llvm/lib/Target/RISCV/RISCVCallingConv.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp index d1c31601f2871..f974daf997b8b 100644 --- a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp +++ b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp @@ -348,7 +348,7 @@ bool llvm::CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT, if (HasCFBranch && (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E)) reportFatalUsageError( - "Alternative static chain register t3 is not usable with EABI."); + "Alternative static chain register t3 is not usable with ILP32E or LP64E ABI."); if (MCRegister Reg = State.AllocateReg(StaticChainReg)) { State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); return false; From ac506b113f12bd7608776f885809257f67b5651f Mon Sep 17 00:00:00 2001 From: Jesse Huang Date: Wed, 4 Jun 2025 01:46:03 -0700 Subject: [PATCH 4/7] clang-format --- llvm/lib/Target/RISCV/RISCVCallingConv.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp index f974daf997b8b..40099b90b232d 100644 --- a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp +++ b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp @@ -347,8 +347,8 @@ bool llvm::CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT, RISCVABI::ABI ABI = Subtarget.getTargetABI(); if (HasCFBranch && (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E)) - reportFatalUsageError( - "Alternative static chain register t3 is not usable with ILP32E or LP64E ABI."); + reportFatalUsageError("Alternative static chain register t3 is not " + "usable with ILP32E or LP64E ABI."); if (MCRegister Reg = State.AllocateReg(StaticChainReg)) { State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); return false; From db6d7b1949f0522a238d0f5b09b14deda3863487 Mon Sep 17 00:00:00 2001 From: Jesse Huang Date: Wed, 11 Jun 2025 13:20:32 +0800 Subject: [PATCH 5/7] Update llvm/lib/Target/RISCV/RISCVCallingConv.cpp Co-authored-by: Sam Elliott --- llvm/lib/Target/RISCV/RISCVCallingConv.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp index 40099b90b232d..a5b6363193556 100644 --- a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp +++ b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp @@ -347,7 +347,7 @@ bool llvm::CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT, RISCVABI::ABI ABI = Subtarget.getTargetABI(); if (HasCFBranch && (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E)) - reportFatalUsageError("Alternative static chain register t3 is not " + 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)); From d1a7d522427673f4e5acfc6aff46ea1106b89b4b Mon Sep 17 00:00:00 2001 From: Jesse Huang Date: Tue, 10 Jun 2025 23:12:12 -0700 Subject: [PATCH 6/7] Add test --- llvm/test/CodeGen/RISCV/nest-register.ll | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llvm/test/CodeGen/RISCV/nest-register.ll b/llvm/test/CodeGen/RISCV/nest-register.ll index 9f8e4e1a2d8d3..6e892e05c4297 100644 --- a/llvm/test/CodeGen/RISCV/nest-register.ll +++ b/llvm/test/CodeGen/RISCV/nest-register.ll @@ -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} From 18a662a7c0e50695d7b22327be206d899f668930 Mon Sep 17 00:00:00 2001 From: Jesse Huang Date: Tue, 10 Jun 2025 23:13:01 -0700 Subject: [PATCH 7/7] clang-format --- llvm/lib/Target/RISCV/RISCVCallingConv.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp index a5b6363193556..cb6117eb0917b 100644 --- a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp +++ b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp @@ -347,8 +347,9 @@ bool llvm::CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT, 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."); + 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;