diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp index 77ea412b7df82..59c95f9c740b5 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -49,6 +49,14 @@ class RISCVInstructionSelector : public InstructionSelector { // the patterns that don't require complex C++. bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const; + // A lowering phase that runs before any selection attempts. + // Returns true if the instruction was modified. + void preISelLower(MachineInstr &MI, MachineIRBuilder &MIB, + MachineRegisterInfo &MRI); + + bool replacePtrWithInt(MachineOperand &Op, MachineIRBuilder &MIB, + MachineRegisterInfo &MRI); + // Custom selection methods bool selectCopy(MachineInstr &MI, MachineRegisterInfo &MRI) const; bool selectConstant(MachineInstr &MI, MachineIRBuilder &MIB, @@ -148,12 +156,14 @@ bool RISCVInstructionSelector::earlySelectShift( } bool RISCVInstructionSelector::select(MachineInstr &MI) { - unsigned Opc = MI.getOpcode(); MachineBasicBlock &MBB = *MI.getParent(); MachineFunction &MF = *MBB.getParent(); MachineRegisterInfo &MRI = MF.getRegInfo(); MachineIRBuilder MIB(MI); + preISelLower(MI, MIB, MRI); + const unsigned Opc = MI.getOpcode(); + if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) { if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI) { const Register DefReg = MI.getOperand(0).getReg(); @@ -243,6 +253,7 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) { switch (Opc) { case TargetOpcode::G_ANYEXT: + case TargetOpcode::G_PTRTOINT: case TargetOpcode::G_TRUNC: return selectCopy(MI, MRI); case TargetOpcode::G_CONSTANT: @@ -264,6 +275,36 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) { } } +bool RISCVInstructionSelector::replacePtrWithInt(MachineOperand &Op, + MachineIRBuilder &MIB, + MachineRegisterInfo &MRI) { + Register PtrReg = Op.getReg(); + assert(MRI.getType(PtrReg).isPointer() && "Operand is not a pointer!"); + + const LLT XLenLLT = LLT::scalar(STI.getXLen()); + auto PtrToInt = MIB.buildPtrToInt(XLenLLT, PtrReg); + MRI.setRegBank(PtrToInt.getReg(0), RBI.getRegBank(RISCV::GPRRegBankID)); + MRI.setType(PtrReg, XLenLLT); + Op.setReg(PtrToInt.getReg(0)); + return select(*PtrToInt); +} + +void RISCVInstructionSelector::preISelLower(MachineInstr &MI, + MachineIRBuilder &MIB, + MachineRegisterInfo &MRI) { + switch (MI.getOpcode()) { + case TargetOpcode::G_PTR_ADD: { + Register DstReg = MI.getOperand(0).getReg(); + const LLT XLenLLT = LLT::scalar(STI.getXLen()); + + replacePtrWithInt(MI.getOperand(1), MIB, MRI); + MI.setDesc(TII.get(TargetOpcode::G_ADD)); + MRI.setType(DstReg, XLenLLT); + break; + } + } +} + void RISCVInstructionSelector::renderNegImm(MachineInstrBuilder &MIB, const MachineInstr &MI, int OpIdx) const { diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/ptradd-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/ptradd-rv32.mir new file mode 100644 index 0000000000000..bc0395685b40e --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/ptradd-rv32.mir @@ -0,0 +1,50 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=riscv32 -run-pass=instruction-select -simplify-mir \ +# RUN: -verify-machineinstrs %s -o - | FileCheck %s +--- +name: add_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; CHECK-LABEL: name: add_i32 + ; CHECK: liveins: $x10, $x11 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; CHECK-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; CHECK-NEXT: $x10 = COPY [[ADD]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(p0) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(p0) = G_PTR_ADD %0, %1 + $x10 = COPY %2(p0) + PseudoRET implicit $x10 + +... +--- +name: addi_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; CHECK-LABEL: name: addi_i32 + ; CHECK: liveins: $x10, $x11 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[COPY]], 20 + ; CHECK-NEXT: $x10 = COPY [[ADDI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(p0) = COPY $x10 + %1:gprb(s32) = G_CONSTANT i32 20 + %2:gprb(p0) = G_PTR_ADD %0, %1 + $x10 = COPY %2(p0) + PseudoRET implicit $x10 + +... diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/ptradd-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/ptradd-rv64.mir new file mode 100644 index 0000000000000..d024a7c659878 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/ptradd-rv64.mir @@ -0,0 +1,50 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=riscv64 -run-pass=instruction-select -simplify-mir \ +# RUN: -verify-machineinstrs %s -o - | FileCheck %s +--- +name: add_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; CHECK-LABEL: name: add_i64 + ; CHECK: liveins: $x10, $x11 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; CHECK-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; CHECK-NEXT: $x10 = COPY [[ADD]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(p0) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(p0) = G_PTR_ADD %0, %1 + $x10 = COPY %2(p0) + PseudoRET implicit $x10 + +... +--- +name: addi_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; CHECK-LABEL: name: addi_i64 + ; CHECK: liveins: $x10, $x11 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[COPY]], 20 + ; CHECK-NEXT: $x10 = COPY [[ADDI]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(p0) = COPY $x10 + %1:gprb(s64) = G_CONSTANT i64 20 + %2:gprb(p0) = G_PTR_ADD %0, %1 + $x10 = COPY %2(p0) + PseudoRET implicit $x10 + +...