diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp --- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -11,11 +11,13 @@ /// \todo This should be generated by TableGen. //===----------------------------------------------------------------------===// +#include "MCTargetDesc/RISCVMatInt.h" #include "RISCVRegisterBankInfo.h" #include "RISCVSubtarget.h" #include "RISCVTargetMachine.h" #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/IR/IntrinsicsRISCV.h" #include "llvm/Support/Debug.h" @@ -35,11 +37,18 @@ const RISCVSubtarget &STI, const RISCVRegisterBankInfo &RBI); - bool select(MachineInstr &I) override; + bool select(MachineInstr &MI) override; static const char *getName() { return DEBUG_TYPE; } private: + const TargetRegisterClass * + getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB, + bool GetAllRegSet = false) const; + bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const; + bool selectCopy(MachineInstr &MI, MachineRegisterInfo &MRI) const; + bool selectConstant(MachineInstr &MI, MachineIRBuilder &MIB, + MachineRegisterInfo &MRI) const; const RISCVSubtarget &STI; const RISCVInstrInfo &TII; @@ -80,17 +89,145 @@ { } -bool RISCVInstructionSelector::select(MachineInstr &I) { +bool RISCVInstructionSelector::select(MachineInstr &MI) { + unsigned Opc = MI.getOpcode(); + MachineBasicBlock &MBB = *MI.getParent(); + MachineFunction &MF = *MBB.getParent(); + MachineRegisterInfo &MRI = MF.getRegInfo(); + MachineIRBuilder MIB(MF); - if (!isPreISelGenericOpcode(I.getOpcode())) { + if (!isPreISelGenericOpcode(Opc)) { // Certain non-generic instructions also need some special handling. + if (MI.isCopy()) + return selectCopy(MI, MRI); + return true; } - if (selectImpl(I, *CoverageInfo)) + if (selectImpl(MI, *CoverageInfo)) + return true; + + MIB.setInstrAndDebugLoc(MI); + + switch (Opc) { + case TargetOpcode::G_ANYEXT: + MI.setDesc(TII.get(TargetOpcode::COPY)); return true; + case TargetOpcode::G_CONSTANT: + if (!selectConstant(MI, MIB, MRI)) + return false; + break; + default: + return false; + } + + MI.eraseFromParent(); + + return true; +} + +const TargetRegisterClass *RISCVInstructionSelector::getRegClassForTypeOnBank( + LLT Ty, const RegisterBank &RB, bool GetAllRegSet) const { + if (RB.getID() == RISCV::GPRRegBankID) { + if (Ty.getSizeInBits() == (STI.is64Bit() ? 64 : 32)) + return &RISCV::GPRRegClass; + } + + // TODO: Non-GPR register classes. + return nullptr; +} + +bool RISCVInstructionSelector::selectCopy(MachineInstr &MI, + MachineRegisterInfo &MRI) const { + Register DstReg = MI.getOperand(0).getReg(); + Register SrcReg = MI.getOperand(1).getReg(); + + if (Register::isPhysicalRegister(SrcReg) && + Register::isPhysicalRegister(DstReg)) + return true; + + if (!Register::isPhysicalRegister(SrcReg)) { + const TargetRegisterClass *SrcRC = getRegClassForTypeOnBank( + MRI.getType(SrcReg), *RBI.getRegBank(SrcReg, MRI, TRI)); + assert(SrcRC && + "Register class not available for LLT, register bank combination"); + + if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI)) { + LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(MI.getOpcode()) + << " operand\n"); + return false; + } + } + if (!Register::isPhysicalRegister(DstReg)) { + const TargetRegisterClass *DstRC = getRegClassForTypeOnBank( + MRI.getType(DstReg), *RBI.getRegBank(DstReg, MRI, TRI)); + assert(DstRC && + "Register class not available for LLT, register bank combination"); + + if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) { + LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(MI.getOpcode()) + << " operand\n"); + return false; + } + } + + return true; +} + +bool RISCVInstructionSelector::selectConstant(MachineInstr &MI, + MachineIRBuilder &MIB, + MachineRegisterInfo &MRI) const { + assert(MI.getOpcode() == TargetOpcode::G_CONSTANT); + Register FinalReg = MI.getOperand(0).getReg(); + int64_t Imm = MI.getOperand(1).getCImm()->getSExtValue(); + + RISCVMatInt::InstSeq Seq = + RISCVMatInt::generateInstSeq(Imm, Subtarget->getFeatureBits()); + unsigned NumInsts = Seq.size(); + Register SrcReg = RISCV::X0; + + for (unsigned i = 0; i < NumInsts; i++) { + Register DstReg = i < NumInsts - 1 + ? MRI.createVirtualRegister(&RISCV::GPRRegClass) + : FinalReg; + const RISCVMatInt::Inst &I = Seq[i]; + MachineInstr *Result; + + switch (I.getOpndKind()) { + case RISCVMatInt::Imm: + // clang-format off + Result = MIB.buildInstr(I.getOpcode()) + .addDef(DstReg) + .addImm(I.getImm()); + // clang-format on + break; + case RISCVMatInt::RegX0: + Result = MIB.buildInstr(I.getOpcode()) + .addDef(DstReg) + .addReg(SrcReg) + .addReg(RISCV::X0); + break; + case RISCVMatInt::RegReg: + Result = MIB.buildInstr(I.getOpcode()) + .addDef(DstReg) + .addReg(SrcReg) + .addReg(SrcReg); + break; + case RISCVMatInt::RegImm: + Result = MIB.buildInstr(I.getOpcode()) + .addDef(DstReg) + .addReg(SrcReg) + .addImm(I.getImm()); + break; + } + + if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI)) + return false; + + SrcReg = DstReg; + } - return false; + return true; } namespace llvm { diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/constant32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/constant32.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/constant32.mir @@ -0,0 +1,125 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=riscv32 -run-pass=instruction-select %s -o - \ +# RUN: | FileCheck %s +--- +name: const_i32_INT_MIN +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i32_INT_MIN + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[LUI:%[0-9]+]]:gpr = LUI 524288 + ; CHECK-NEXT: $x10 = COPY [[LUI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = G_CONSTANT i32 -2147483648 + $x10 = COPY %0(s32) + PseudoRET implicit $x10 + +... +--- +name: const_i32_neg_2147483000 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i32_neg_2147483000 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[LUI:%[0-9]+]]:gpr = LUI 524288 + ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], 648 + ; CHECK-NEXT: $x10 = COPY [[ADDI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = G_CONSTANT i32 -2147483000 + $x10 = COPY %0(s32) + PseudoRET implicit $x10 + +... +--- +name: const_i32_INT_MAX +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i32_INT_MAX + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[LUI:%[0-9]+]]:gpr = LUI 524288 + ; CHECK-NEXT: $x10 = COPY [[LUI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = G_CONSTANT i32 2147483648 + $x10 = COPY %0(s32) + PseudoRET implicit $x10 + +... +--- +name: const_i32_2147483000 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i32_2147483000 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[LUI:%[0-9]+]]:gpr = LUI 524288 + ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], -648 + ; CHECK-NEXT: $x10 = COPY [[ADDI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = G_CONSTANT i32 2147483000 + $x10 = COPY %0(s32) + PseudoRET implicit $x10 + +... +--- +name: const_i32_256 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i32_256 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 256 + ; CHECK-NEXT: $x10 = COPY [[ADDI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = G_CONSTANT i32 256 + $x10 = COPY %0(s32) + PseudoRET implicit $x10 + +... +--- +name: const_i32_0 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i32_0 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 0 + ; CHECK-NEXT: $x10 = COPY [[ADDI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = G_CONSTANT i32 0 + $x10 = COPY %0(s32) + PseudoRET implicit $x10 + +... diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/constant64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/constant64.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/constant64.mir @@ -0,0 +1,256 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=riscv64 -run-pass=instruction-select %s -o - \ +# RUN: | FileCheck %s +--- +name: const_i64_INT_MIN +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i64_INT_MIN + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, -1 + ; CHECK-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADDI]], 63 + ; CHECK-NEXT: $x10 = COPY [[SLLI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = G_CONSTANT i64 -9223372036854775808 + $x10 = COPY %0(s64) + PseudoRET implicit $x10 + +... +--- +name: const_i64_neg_9223372036854775000 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i64_neg_9223372036854775000 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, -1 + ; CHECK-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADDI]], 63 + ; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI [[SLLI]], 808 + ; CHECK-NEXT: $x10 = COPY [[ADDI1]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = G_CONSTANT i64 -9223372036854775000 + $x10 = COPY %0(s64) + PseudoRET implicit $x10 + +... +--- +name: const_i64_INT_MAX +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i64_INT_MAX + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, -1 + ; CHECK-NEXT: [[SRLI:%[0-9]+]]:gpr = SRLI [[ADDI]], 1 + ; CHECK-NEXT: $x10 = COPY [[SRLI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = G_CONSTANT i64 9223372036854775807 + $x10 = COPY %0(s64) + PseudoRET implicit $x10 + +... +--- +name: const_i64_9223372036854775000 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i64_9223372036854775000 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, -1615 + ; CHECK-NEXT: [[SRLI:%[0-9]+]]:gpr = SRLI [[ADDI]], 1 + ; CHECK-NEXT: $x10 = COPY [[SRLI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = G_CONSTANT i64 9223372036854775000 + $x10 = COPY %0(s64) + PseudoRET implicit $x10 + +... +--- +name: const_i64_256 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i64_256 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 256 + ; CHECK-NEXT: $x10 = COPY [[ADDI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = G_CONSTANT i64 256 + $x10 = COPY %0(s64) + PseudoRET implicit $x10 + +... +--- +name: const_i64_0 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i64_0 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 0 + ; CHECK-NEXT: $x10 = COPY [[ADDI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = G_CONSTANT i64 0 + $x10 = COPY %0(s64) + PseudoRET implicit $x10 + +... +--- +name: const_i32_INT_MIN +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i32_INT_MIN + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[LUI:%[0-9]+]]:gpr = LUI 524288 + ; CHECK-NEXT: $x10 = COPY [[LUI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = G_CONSTANT i32 -2147483648 + %1:gprb(s64) = G_ANYEXT %0(s32) + $x10 = COPY %1(s64) + PseudoRET implicit $x10 + +... +--- +name: const_i32_neg_2147483000 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i32_neg_2147483000 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[LUI:%[0-9]+]]:gpr = LUI 524288 + ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[LUI]], 648 + ; CHECK-NEXT: $x10 = COPY [[ADDIW]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = G_CONSTANT i32 -2147483000 + %1:gprb(s64) = G_ANYEXT %0(s32) + $x10 = COPY %1(s64) + PseudoRET implicit $x10 + +... +--- +name: const_i32_INT_MAX +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i32_INT_MAX + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[LUI:%[0-9]+]]:gpr = LUI 524288 + ; CHECK-NEXT: $x10 = COPY [[LUI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = G_CONSTANT i32 2147483648 + %1:gprb(s64) = G_ANYEXT %0(s32) + $x10 = COPY %1(s64) + PseudoRET implicit $x10 + +... +--- +name: const_i32_2147483000 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i32_2147483000 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[LUI:%[0-9]+]]:gpr = LUI 524288 + ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[LUI]], -648 + ; CHECK-NEXT: $x10 = COPY [[ADDIW]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = G_CONSTANT i32 2147483000 + %1:gprb(s64) = G_ANYEXT %0(s32) + $x10 = COPY %1(s64) + PseudoRET implicit $x10 + +... +--- +name: const_i32_256 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i32_256 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 256 + ; CHECK-NEXT: $x10 = COPY [[ADDI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = G_CONSTANT i32 256 + %1:gprb(s64) = G_ANYEXT %0(s32) + $x10 = COPY %1(s64) + PseudoRET implicit $x10 + +... +--- +name: const_i32_0 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10 + + ; CHECK-LABEL: name: const_i32_0 + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 0 + ; CHECK-NEXT: $x10 = COPY [[ADDI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = G_CONSTANT i32 0 + %1:gprb(s64) = G_ANYEXT %0(s32) + $x10 = COPY %1(s64) + PseudoRET implicit $x10 + +... diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/copy32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/copy32.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/copy32.mir @@ -0,0 +1,71 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=riscv32 -run-pass=instruction-select -simplify-mir -verify-machineinstrs %s -o - \ +# RUN: | FileCheck -check-prefix=RV32I %s + +--- +name: virt_to_phys +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + + ; RV32I-LABEL: name: virt_to_phys + ; RV32I: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 1 + ; RV32I-NEXT: $x10 = COPY [[ADDI]] + ; RV32I-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = G_CONSTANT i32 1 + $x10 = COPY %0(s32) + PseudoRET implicit $x10 + +... +--- +name: phys_to_phys +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: phys_to_phys + ; RV32I: liveins: $x10, $x11 + ; RV32I-NEXT: {{ $}} + ; RV32I-NEXT: $x10 = COPY $x11 + ; RV32I-NEXT: PseudoRET implicit $x10 + $x10 = COPY $x11 + PseudoRET implicit $x10 + +... +--- +name: virt_to_virt +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + + ; RV32I-LABEL: name: virt_to_virt + ; RV32I: PseudoRET + %0:gprb(s32) = G_CONSTANT i32 1 + %1:gprb(s32) = COPY %0(s32) + PseudoRET + +... +--- +name: phys_to_virt +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10 + + ; RV32I-LABEL: name: phys_to_virt + ; RV32I: liveins: $x10 + ; RV32I-NEXT: {{ $}} + ; RV32I-NEXT: PseudoRET + %0:gprb(s32) = COPY $x10 + PseudoRET + +... diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/copy64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/copy64.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/copy64.mir @@ -0,0 +1,71 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=riscv64 -run-pass=instruction-select -simplify-mir -verify-machineinstrs %s -o - \ +# RUN: | FileCheck -check-prefix=RV64I %s + +--- +name: virt_to_phys +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + + ; RV64I-LABEL: name: virt_to_phys + ; RV64I: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 1 + ; RV64I-NEXT: $x10 = COPY [[ADDI]] + ; RV64I-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = G_CONSTANT i64 1 + $x10 = COPY %0(s64) + PseudoRET implicit $x10 + +... +--- +name: phys_to_phys +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: phys_to_phys + ; RV64I: liveins: $x10, $x11 + ; RV64I-NEXT: {{ $}} + ; RV64I-NEXT: $x10 = COPY $x11 + ; RV64I-NEXT: PseudoRET implicit $x10 + $x10 = COPY $x11 + PseudoRET implicit $x10 + +... +--- +name: virt_to_virt +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + + ; RV64I-LABEL: name: virt_to_virt + ; RV64I: PseudoRET + %0:gprb(s64) = G_CONSTANT i64 1 + %1:gprb(s64) = COPY %0(s64) + PseudoRET + +... +--- +name: phys_to_virt +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10 + + ; RV64I-LABEL: name: phys_to_virt + ; RV64I: liveins: $x10 + ; RV64I-NEXT: {{ $}} + ; RV64I-NEXT: PseudoRET + %0:gprb(s64) = COPY $x10 + PseudoRET + +...