Skip to content

Commit f27f369

Browse files
authored
[RISCV] Remove interrupt handler special case from RISCVFrameLowering::determineCalleeSaves. (#88069)
This code was trying to save temporary argument registers in interrupt handler functions that contain calls. With the exception that all FP registers are saved including the normally callee saved registers. If all of the callees use an FP ABI and the interrupt handler doesn't touch the normally callee saved FP registers, we don't need to save them. It doesn't appear that we need to special case functions with calls. The normal callee saved register handling will already check each of the calls and consider a register clobbered if the call doesn't explicitly say it is preserved. All of the test changes are from the removal of the FP callee saved registers. There are tests for interrupt handlers with F and D extension that use ilp32 or lp64 ABIs that are not affected by this change. They still save the FP callee saved registers as they should. gcc appears to have a bug where the D extension being enabled with the ilp32f or lp64f ABI does not save the FP callee saved regs. The callee would only save/restore the lower 32 bits and clobber the upper bits. LLVM saves the FP callee saved regs in this case and there is an unchanged test for it. The unnecessary save/restore was raised in this thread https://discourse.llvm.org/t/has-bugs-when-optimizing-save-restore-csrs-by-changing-csr-xlen-f32-interrupt/78200/1
1 parent c54afe5 commit f27f369

File tree

3 files changed

+675
-955
lines changed

3 files changed

+675
-955
lines changed

llvm/lib/Target/RISCV/RISCVFrameLowering.cpp

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,46 +1001,6 @@ void RISCVFrameLowering::determineCalleeSaves(MachineFunction &MF,
10011001
// Mark BP as used if function has dedicated base pointer.
10021002
if (hasBP(MF))
10031003
SavedRegs.set(RISCVABI::getBPReg());
1004-
1005-
// If interrupt is enabled and there are calls in the handler,
1006-
// unconditionally save all Caller-saved registers and
1007-
// all FP registers, regardless whether they are used.
1008-
MachineFrameInfo &MFI = MF.getFrameInfo();
1009-
auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
1010-
1011-
if (MF.getFunction().hasFnAttribute("interrupt") && MFI.hasCalls()) {
1012-
1013-
static const MCPhysReg CSRegs[] = { RISCV::X1, /* ra */
1014-
RISCV::X5, RISCV::X6, RISCV::X7, /* t0-t2 */
1015-
RISCV::X10, RISCV::X11, /* a0-a1, a2-a7 */
1016-
RISCV::X12, RISCV::X13, RISCV::X14, RISCV::X15, RISCV::X16, RISCV::X17,
1017-
RISCV::X28, RISCV::X29, RISCV::X30, RISCV::X31 /* t3-t6 */
1018-
};
1019-
1020-
for (auto Reg : CSRegs)
1021-
SavedRegs.set(Reg);
1022-
1023-
// According to psABI, if ilp32e/lp64e ABIs are used with an ISA that
1024-
// has any of the registers x16-x31 and f0-f31, then these registers are
1025-
// considered temporaries, so we should also save x16-x31 here.
1026-
if (STI.getTargetABI() == RISCVABI::ABI_ILP32E ||
1027-
STI.getTargetABI() == RISCVABI::ABI_LP64E) {
1028-
for (MCPhysReg Reg = RISCV::X16; Reg <= RISCV::X31; Reg++)
1029-
SavedRegs.set(Reg);
1030-
}
1031-
1032-
if (Subtarget.hasStdExtF()) {
1033-
1034-
// If interrupt is enabled, this list contains all FP registers.
1035-
const MCPhysReg * Regs = MF.getRegInfo().getCalleeSavedRegs();
1036-
1037-
for (unsigned i = 0; Regs[i]; ++i)
1038-
if (RISCV::FPR16RegClass.contains(Regs[i]) ||
1039-
RISCV::FPR32RegClass.contains(Regs[i]) ||
1040-
RISCV::FPR64RegClass.contains(Regs[i]))
1041-
SavedRegs.set(Regs[i]);
1042-
}
1043-
}
10441004
}
10451005

10461006
std::pair<int64_t, Align>

0 commit comments

Comments
 (0)