Index: llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp =================================================================== --- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -674,6 +674,9 @@ return true; } +#define GET_REGISTER_MATCHER +#include "RISCVGenAsmMatcher.inc" + void RISCVDAGToDAGISel::Select(SDNode *Node) { // If we have a custom node, we have already selected. if (Node->isMachineOpcode()) { @@ -1843,6 +1846,19 @@ ReplaceNode(Node, Load); return; } + case ISD::WRITE_REGISTER: { + const auto *MD = cast(Node->getOperand(1)); + const auto *RegString = cast(MD->getMD()->getOperand(0)); + + Register Reg = MatchRegisterAltName(RegString->getString()); + if (Reg == RISCV::NoRegister) + Reg = MatchRegisterName(RegString->getString()); + assert (Reg != RISCV::NoRegister && "Invalid register name at WRITE_REGISTER"); + + MachineRegisterInfo &MRI = MF->getRegInfo(); + MRI.disableCalleeSavedRegister(Reg); + break; + } } // Select the default instruction. Index: llvm/test/CodeGen/RISCV/get-register-noreserve.ll =================================================================== --- llvm/test/CodeGen/RISCV/get-register-noreserve.ll +++ llvm/test/CodeGen/RISCV/get-register-noreserve.ll @@ -21,6 +21,26 @@ ret void } +define i32 @get_gp() nounwind { +; CHECK-LABEL: get_gp: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mv a0, gp +; CHECK-NEXT: ret +entry: + %sp = call i32 @llvm.read_register.i32(metadata !3) + ret i32 %sp +} + +define void @set_gp(i32 %val) nounwind { +; CHECK-LABEL: set_gp: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mv gp, a0 +; CHECK-NEXT: ret +entry: + call void @llvm.write_register.i32(metadata !3, i32 %val) + ret void +} + define i32 @get_tp_arch_name() nounwind { ; CHECK-LABEL: get_tp_arch_name: ; CHECK: # %bb.0: # %entry @@ -45,6 +65,7 @@ declare i32 @llvm.read_register.i32(metadata) nounwind declare void @llvm.write_register.i32(metadata, i32) nounwind -!0 = !{!"sp\00"} -!1 = !{!"x4\00"} +!0 = !{!"sp"} +!1 = !{!"x4"} !2 = !{!"vlenb"} +!3 = !{!"gp"}