[RISCV] Add llvm.read.register support for vlenb

This patch adds minimal support for lowering an read.register intrinsic with vlenb as the argument. Note that vlenb is an implementation constant, so it is never allocatable.

This was split off a patch to eventually replace PseudoReadVLENB with a COPY MI because doing so revealed a couple of optimization opportunities which really seemed to warrant individual patches and tests. To write those patches, I need a way to write the tests involving vlenb, and read.register seemed like the right testing hook.

Differential Revision: https://reviews.llvm.org/D125552
This commit is contained in:
Philip Reames
2022-05-13 09:01:19 -07:00
parent 1d7b5cd5bf
commit af5e09b7d9
4 changed files with 29 additions and 0 deletions

View File

@@ -264,6 +264,16 @@ void RISCVInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
return;
}
// Handle copy from csr
// TODO: Handle sysreg lookup generically and remove vlenb restriction.
if (RISCV::VCSRRegClass.contains(SrcReg) && SrcReg == RISCV::VLENB &&
RISCV::GPRRegClass.contains(DstReg)) {
BuildMI(MBB, MBBI, DL, get(RISCV::CSRRS), DstReg)
.addImm(RISCVSysReg::lookupSysRegByName("VLENB")->Encoding)
.addReg(RISCV::X0);
return;
}
// FPR->FPR copies and VR->VR copies.
unsigned Opc;
bool IsScalableVector = true;

View File

@@ -102,6 +102,7 @@ BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
markSuperRegs(Reserved, RISCV::VTYPE);
markSuperRegs(Reserved, RISCV::VXSAT);
markSuperRegs(Reserved, RISCV::VXRM);
markSuperRegs(Reserved, RISCV::VLENB); // vlenb (constant)
// Floating point environment registers.
markSuperRegs(Reserved, RISCV::FRM);

View File

@@ -462,6 +462,12 @@ let RegAltNameIndices = [ABIRegAltName] in {
DwarfRegNum<[!add(4096, SysRegVLENB.Encoding)]>;
}
def VCSR : RegisterClass<"RISCV", [XLenVT], 32,
(add VTYPE, VL, VLENB)> {
let RegInfos = XLenRI;
}
foreach m = [1, 2, 4] in {
foreach n = NFList<m>.L in {
def "VN" # n # "M" # m # "NoV0": RegisterTuples<

View File

@@ -31,8 +31,20 @@ entry:
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
}
declare i32 @llvm.read_register.i32(metadata) nounwind
declare void @llvm.write_register.i32(metadata, i32) nounwind
!0 = !{!"sp\00"}
!1 = !{!"x4\00"}
!2 = !{!"vlenb"}