diff --git a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h index bfaa6450779ae..6b14d1476568f 100644 --- a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h +++ b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h @@ -339,6 +339,8 @@ class TargetSubtargetInfo : public MCSubtargetInfo { // Conservatively assume such instructions exist by default. return true; } + + virtual bool isRegisterReservedByUser(Register R) const { return false; } }; } // end namespace llvm diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp index fcedb302d228c..6f636a161f500 100644 --- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp +++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp @@ -635,7 +635,13 @@ const MCPhysReg *MachineRegisterInfo::getCalleeSavedRegs() const { if (IsUpdatedCSRsInitialized) return UpdatedCSRs.data(); - return getTargetRegisterInfo()->getCalleeSavedRegs(MF); + const MCPhysReg *Regs = getTargetRegisterInfo()->getCalleeSavedRegs(MF); + + for (unsigned I = 0; Regs[I]; ++I) + if (MF->getSubtarget().isRegisterReservedByUser(Regs[I])) + MF->getRegInfo().disableCalleeSavedRegister(Regs[I]); + + return Regs; } void MachineRegisterInfo::setCalleeSavedRegs(ArrayRef CSRs) { diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 831b0b30d47fc..c8c495327c383 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -19884,8 +19884,7 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI, // reserved, if so report an error. Do the same for the return address if this // is not a tailcall. validateCCReservedRegs(RegsToPass, MF); - if (!IsTailCall && - MF.getSubtarget().isRegisterReservedByUser(RISCV::X1)) + if (!IsTailCall && MF.getSubtarget().isRegisterReservedByUser(RISCV::X1)) MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{ MF.getFunction(), "Return address register required, but has been reserved."}); diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp index 26195ef721db3..4b3b1d5154e9f 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -163,7 +163,7 @@ BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const { bool RISCVRegisterInfo::isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const { - return !MF.getSubtarget().isRegisterReservedByUser(PhysReg); + return !MF.getSubtarget().isRegisterReservedByUser(PhysReg); } const uint32_t *RISCVRegisterInfo::getNoPreservedMask() const { diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h index f59a3737ae76f..99edf22eb0791 100644 --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -218,7 +218,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo { TargetABI == RISCVABI::ABI_ILP32 || TargetABI == RISCVABI::ABI_ILP32E; } - bool isRegisterReservedByUser(Register i) const { + bool isRegisterReservedByUser(Register i) const override { assert(i < RISCV::NUM_TARGET_REGS && "Register out of range"); return UserReservedRegister[i]; } diff --git a/llvm/test/CodeGen/RISCV/fixed-csr.ll b/llvm/test/CodeGen/RISCV/fixed-csr.ll new file mode 100644 index 0000000000000..f39085132e4a2 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/fixed-csr.ll @@ -0,0 +1,35 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=riscv64 -mattr=+reserve-x24 < %s | FileCheck %s + +define noundef signext i32 @foo() { +; CHECK-LABEL: foo: +; CHECK: # %bb.0: +; CHECK-NEXT: li s8, 321 +; CHECK-NEXT: li a0, 0 +; CHECK-NEXT: ret + tail call void @llvm.write_register.i64(metadata !0, i64 321) + ret i32 0 +} + +declare void @llvm.write_register.i64(metadata, i64) + +define noundef signext i32 @bar() nounwind { +; CHECK-LABEL: bar: +; CHECK: # %bb.0: +; CHECK-NEXT: addi sp, sp, -16 +; CHECK-NEXT: sd s9, 8(sp) # 8-byte Folded Spill +; CHECK-NEXT: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: li s8, 321 +; CHECK-NEXT: li a0, 0 +; CHECK-NEXT: ld s9, 8(sp) # 8-byte Folded Reload +; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: ret + tail call void asm sideeffect "", "~{x25}"() #3 + tail call void @llvm.write_register.i64(metadata !0, i64 321) + ret i32 0 +} + +!llvm.named.register.x24 = !{!0} +!0 = !{!"x24"} +