diff --git a/llvm/lib/Target/RISCV/RISCVCallingConv.td b/llvm/lib/Target/RISCV/RISCVCallingConv.td index ad06f47743770..98e05b7f8eca7 100644 --- a/llvm/lib/Target/RISCV/RISCVCallingConv.td +++ b/llvm/lib/Target/RISCV/RISCVCallingConv.td @@ -42,6 +42,8 @@ def CSR_ILP32D_LP64D_V // Needed for implementation of RISCVRegisterInfo::getNoPreservedMask() def CSR_NoRegs : CalleeSavedRegs<(add)>; +def CSR_IPRA : CalleeSavedRegs<(add X1)>; + // Interrupt handler needs to save/restore all registers that are used, // both Caller and Callee saved registers. def CSR_Interrupt : CalleeSavedRegs<(add X1, (sequence "X%u", 5, 31))>; diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp index b0a52698c1e9f..7a99bfd1b2512 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -55,6 +55,11 @@ RISCVRegisterInfo::RISCVRegisterInfo(unsigned HwMode) : RISCVGenRegisterInfo(RISCV::X1, /*DwarfFlavour*/0, /*EHFlavor*/0, /*PC*/0, HwMode) {} +const MCPhysReg * +RISCVRegisterInfo::getIPRACSRegs(const MachineFunction *MF) const { + return CSR_IPRA_SaveList; +} + const MCPhysReg * RISCVRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { auto &Subtarget = MF->getSubtarget(); diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.h b/llvm/lib/Target/RISCV/RISCVRegisterInfo.h index 3ab79694e175c..6c4e9c7b1bdc7 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.h +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.h @@ -62,6 +62,8 @@ struct RISCVRegisterInfo : public RISCVGenRegisterInfo { const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override; + const MCPhysReg *getIPRACSRegs(const MachineFunction *MF) const override; + BitVector getReservedRegs(const MachineFunction &MF) const override; bool isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const override; diff --git a/llvm/test/CodeGen/RISCV/ipra.ll b/llvm/test/CodeGen/RISCV/ipra.ll index 717b778bcde37..0bcded99c5975 100644 --- a/llvm/test/CodeGen/RISCV/ipra.ll +++ b/llvm/test/CodeGen/RISCV/ipra.ll @@ -63,26 +63,29 @@ entry: ret i32 0 } -; FIXME: this function calls another function but doesn't save/restore ra define internal void @foobar(ptr %live_throughout.0.val) norecurse nounwind { ; RV64-LABEL: foobar: ; RV64: # %bb.0: # %entry ; RV64-NEXT: addi sp, sp, -48 +; RV64-NEXT: sd ra, 40(sp) # 8-byte Folded Spill ; RV64-NEXT: mv a1, a0 -; RV64-NEXT: addi a0, sp, 16 -; RV64-NEXT: addi a2, sp, 12 +; RV64-NEXT: addi a0, sp, 8 +; RV64-NEXT: addi a2, sp, 4 ; RV64-NEXT: call bmp_iter_set_init +; RV64-NEXT: ld ra, 40(sp) # 8-byte Folded Reload ; RV64-NEXT: addi sp, sp, 48 ; RV64-NEXT: ret ; ; RV32-LABEL: foobar: ; RV32: # %bb.0: # %entry -; RV32-NEXT: addi sp, sp, -32 +; RV32-NEXT: addi sp, sp, -48 +; RV32-NEXT: sw ra, 44(sp) # 4-byte Folded Spill ; RV32-NEXT: mv a1, a0 -; RV32-NEXT: addi a0, sp, 8 -; RV32-NEXT: addi a2, sp, 4 +; RV32-NEXT: addi a0, sp, 16 +; RV32-NEXT: addi a2, sp, 12 ; RV32-NEXT: call bmp_iter_set_init -; RV32-NEXT: addi sp, sp, 32 +; RV32-NEXT: lw ra, 44(sp) # 4-byte Folded Reload +; RV32-NEXT: addi sp, sp, 48 ; RV32-NEXT: ret ; ; RV64-WITHFP-LABEL: foobar: