diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp index 1fb1c865ba32b..7059d249572e4 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -149,7 +149,8 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) .clampScalar(0, sXLen, sXLen); getActionDefinitionsBuilder( - {G_UADDE, G_UADDO, G_USUBE, G_USUBO}).lower(); + {G_UADDE, G_UADDO, G_USUBE, G_USUBO, G_READ_REGISTER, G_WRITE_REGISTER}) + .lower(); getActionDefinitionsBuilder({G_SADDE, G_SADDO, G_SSUBE, G_SSUBO}) .minScalar(0, sXLen) diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp index 9f9ae2f5c6dc6..28764f7e2fd7b 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp @@ -112,6 +112,19 @@ using namespace llvm; RISCVRegisterBankInfo::RISCVRegisterBankInfo(unsigned HwMode) : RISCVGenRegisterBankInfo(HwMode) {} +const RegisterBank & +RISCVRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC, + LLT Ty) const { + switch (RC.getID()) { + // Vector control and status register class + case RISCV::VCSRRegClassID: + return getRegBank(RISCV::GPRBRegBankID); + default: + // For all GPR register classes and others, use the default implementation + return RISCVGenRegisterBankInfo::getRegBankFromRegClass(RC, Ty); + } +} + static const RegisterBankInfo::ValueMapping *getFPValueMapping(unsigned Size) { unsigned Idx; switch (Size) { diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.h b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.h index 79dddb73a2373..c5e4b2ae8621b 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.h +++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.h @@ -36,6 +36,9 @@ class RISCVRegisterBankInfo final : public RISCVGenRegisterBankInfo { const InstructionMapping & getInstrMapping(const MachineInstr &MI) const override; + const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC, + LLT Ty) const override; + private: /// \returns true if \p MI only uses and defines FPRs. bool hasFPConstraints(const MachineInstr &MI, const MachineRegisterInfo &MRI, diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/get-register-noreserve.ll b/llvm/test/CodeGen/RISCV/GlobalISel/get-register-noreserve.ll new file mode 100644 index 0000000000000..5712afb8b48a5 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/get-register-noreserve.ll @@ -0,0 +1,46 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=riscv32 -global-isel | FileCheck %s + +define i32 @get_stack() nounwind { +; CHECK-LABEL: get_stack: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mv a0, sp +; CHECK-NEXT: ret +entry: + %sp = call i32 @llvm.read_register.i32(metadata !0) + ret i32 %sp +} + +define void @set_stack(i32 %val) nounwind { +; CHECK-LABEL: set_stack: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mv sp, a0 +; CHECK-NEXT: ret +entry: + call void @llvm.write_register.i32(metadata !0, i32 %val) + ret void +} + +define i32 @get_tp_arch_name() nounwind { +; CHECK-LABEL: get_tp_arch_name: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mv a0, tp +; CHECK-NEXT: ret +entry: + %sp = call i32 @llvm.read_register.i32(metadata !1) + ret i32 %sp +} + +define i32 @get_csr_vlenb() nounwind { +; CHECK-LABEL: get_csr_vlenb: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: csrr a0, vlenb +; CHECK-NEXT: ret +entry: + %sp = call i32 @llvm.read_register.i32(metadata !2) + ret i32 %sp +} + +!0 = !{!"sp\00"} +!1 = !{!"x4\00"} +!2 = !{!"vlenb"} diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir index ff8b8faee5c15..a823a4ccf3e46 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir @@ -852,11 +852,13 @@ # DEBUG-NEXT:.. type index coverage check SKIPPED: no rules defined # DEBUG-NEXT:.. imm index coverage check SKIPPED: no rules defined # DEBUG-NEXT: G_READ_REGISTER (opcode {{[0-9]+}}): 1 type index, 0 imm indices -# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined -# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}} +# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected +# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected # DEBUG-NEXT: G_WRITE_REGISTER (opcode {{[0-9]+}}): 1 type index, 0 imm indices -# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined -# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}} +# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected +# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected # DEBUG-NEXT: G_MEMCPY (opcode {{[0-9]+}}): 3 type indices, 1 imm index # DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected # DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected