Skip to content

Commit 84efad0

Browse files
[RISCV][MRI] Account for fixed registers when determining callee saved regs (#115756)
This fixes https://discourse.llvm.org/t/fixed-register-being-spill-and-restored-in-clang/83058. We need to do it in `MachineRegisterInfo::getCalleeSavedRegs` instead of `RISCVRegisterInfo::getCalleeSavedRegs` since the MF argument of `TargetRegisterInfo:::getCalleeSavedRegs` is `const`, so we can't call `MF->getRegInfo().disableCalleeSavedRegister` there. So to put it in `MachineRegisterInfo::getCalleeSavedRegs`, we move `isRegisterReservedByUser` into `TargetSubtargetInfo`.
1 parent 1d95825 commit 84efad0

File tree

6 files changed

+47
-5
lines changed

6 files changed

+47
-5
lines changed

llvm/include/llvm/CodeGen/TargetSubtargetInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,8 @@ class TargetSubtargetInfo : public MCSubtargetInfo {
349349
// Conservatively assume such instructions exist by default.
350350
return true;
351351
}
352+
353+
virtual bool isRegisterReservedByUser(Register R) const { return false; }
352354
};
353355
} // end namespace llvm
354356

llvm/lib/CodeGen/MachineRegisterInfo.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,13 @@ const MCPhysReg *MachineRegisterInfo::getCalleeSavedRegs() const {
635635
if (IsUpdatedCSRsInitialized)
636636
return UpdatedCSRs.data();
637637

638-
return getTargetRegisterInfo()->getCalleeSavedRegs(MF);
638+
const MCPhysReg *Regs = getTargetRegisterInfo()->getCalleeSavedRegs(MF);
639+
640+
for (unsigned I = 0; Regs[I]; ++I)
641+
if (MF->getSubtarget().isRegisterReservedByUser(Regs[I]))
642+
MF->getRegInfo().disableCalleeSavedRegister(Regs[I]);
643+
644+
return Regs;
639645
}
640646

641647
void MachineRegisterInfo::setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs) {

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20076,8 +20076,7 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
2007620076
// reserved, if so report an error. Do the same for the return address if this
2007720077
// is not a tailcall.
2007820078
validateCCReservedRegs(RegsToPass, MF);
20079-
if (!IsTailCall &&
20080-
MF.getSubtarget<RISCVSubtarget>().isRegisterReservedByUser(RISCV::X1))
20079+
if (!IsTailCall && MF.getSubtarget().isRegisterReservedByUser(RISCV::X1))
2008120080
MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{
2008220081
MF.getFunction(),
2008320082
"Return address register required, but has been reserved."});

llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
162162

163163
bool RISCVRegisterInfo::isAsmClobberable(const MachineFunction &MF,
164164
MCRegister PhysReg) const {
165-
return !MF.getSubtarget<RISCVSubtarget>().isRegisterReservedByUser(PhysReg);
165+
return !MF.getSubtarget().isRegisterReservedByUser(PhysReg);
166166
}
167167

168168
const uint32_t *RISCVRegisterInfo::getNoPreservedMask() const {

llvm/lib/Target/RISCV/RISCVSubtarget.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
231231
TargetABI == RISCVABI::ABI_ILP32 ||
232232
TargetABI == RISCVABI::ABI_ILP32E;
233233
}
234-
bool isRegisterReservedByUser(Register i) const {
234+
bool isRegisterReservedByUser(Register i) const override {
235235
assert(i < RISCV::NUM_TARGET_REGS && "Register out of range");
236236
return UserReservedRegister[i];
237237
}

llvm/test/CodeGen/RISCV/fixed-csr.ll

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x24 < %s | FileCheck %s
3+
4+
define noundef signext i32 @foo() {
5+
; CHECK-LABEL: foo:
6+
; CHECK: # %bb.0:
7+
; CHECK-NEXT: li s8, 321
8+
; CHECK-NEXT: li a0, 0
9+
; CHECK-NEXT: ret
10+
tail call void @llvm.write_register.i64(metadata !0, i64 321)
11+
ret i32 0
12+
}
13+
14+
declare void @llvm.write_register.i64(metadata, i64)
15+
16+
define noundef signext i32 @bar() nounwind {
17+
; CHECK-LABEL: bar:
18+
; CHECK: # %bb.0:
19+
; CHECK-NEXT: addi sp, sp, -16
20+
; CHECK-NEXT: sd s9, 8(sp) # 8-byte Folded Spill
21+
; CHECK-NEXT: #APP
22+
; CHECK-NEXT: #NO_APP
23+
; CHECK-NEXT: li s8, 321
24+
; CHECK-NEXT: li a0, 0
25+
; CHECK-NEXT: ld s9, 8(sp) # 8-byte Folded Reload
26+
; CHECK-NEXT: addi sp, sp, 16
27+
; CHECK-NEXT: ret
28+
tail call void asm sideeffect "", "~{x25}"() #3
29+
tail call void @llvm.write_register.i64(metadata !0, i64 321)
30+
ret i32 0
31+
}
32+
33+
!llvm.named.register.x24 = !{!0}
34+
!0 = !{!"x24"}
35+

0 commit comments

Comments
 (0)