diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp index 4f97a0d84f686..4f18b2bb576fe 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -44,11 +44,17 @@ class RISCVInstructionSelector : public InstructionSelector { const TargetRegisterClass * getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB) const; + // tblgen-erated 'select' implementation, used as the initial selector for + // the patterns that don't require complex C++. bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const; + + // Custom selection methods bool selectCopy(MachineInstr &MI, MachineRegisterInfo &MRI) const; bool selectConstant(MachineInstr &MI, MachineIRBuilder &MIB, MachineRegisterInfo &MRI) const; bool selectSExtInreg(MachineInstr &MI, MachineIRBuilder &MIB) const; + bool selectSelect(MachineInstr &MI, MachineIRBuilder &MIB, + MachineRegisterInfo &MRI) const; bool earlySelectShift(unsigned Opc, MachineInstr &I, MachineIRBuilder &MIB, const MachineRegisterInfo &MRI); @@ -239,6 +245,8 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) { } case TargetOpcode::G_SEXT_INREG: return selectSExtInreg(MI, MIB); + case TargetOpcode::G_SELECT: + return selectSelect(MI, MIB, MRI); default: return false; } @@ -376,6 +384,27 @@ bool RISCVInstructionSelector::selectSExtInreg(MachineInstr &MI, return true; } +bool RISCVInstructionSelector::selectSelect(MachineInstr &MI, + MachineIRBuilder &MIB, + MachineRegisterInfo &MRI) const { + // TODO: Currently we check that the conditional code passed to G_SELECT is + // not equal to zero; however, in the future, we might want to try and check + // if the conditional code comes from a G_ICMP. If it does, we can directly + // use G_ICMP to get the first three input operands of the + // Select_GPR_Using_CC_GPR. This might be done here, or in the appropriate + // combiner. + assert(MI.getOpcode() == TargetOpcode::G_SELECT); + MachineInstr *Result = MIB.buildInstr(RISCV::Select_GPR_Using_CC_GPR) + .addDef(MI.getOperand(0).getReg()) + .addReg(MI.getOperand(1).getReg()) + .addReg(RISCV::X0) + .addImm(RISCVCC::COND_NE) + .addReg(MI.getOperand(2).getReg()) + .addReg(MI.getOperand(3).getReg()); + MI.eraseFromParent(); + return constrainSelectedInstRegOperands(*Result, TII, TRI, RBI); +} + namespace llvm { InstructionSelector * createRISCVInstructionSelector(const RISCVTargetMachine &TM, diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/select-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/select-rv32.mir new file mode 100644 index 0000000000000..828835dac8f80 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/select-rv32.mir @@ -0,0 +1,55 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=riscv32 -run-pass=instruction-select --simplify-mir \ +# RUN: -verify-machineinstrs %s -o - | FileCheck %s +--- +name: select_s32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10, $x11, $x12 + + ; CHECK-LABEL: name: select_s32 + ; CHECK: liveins: $x10, $x11, $x12 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12 + ; CHECK-NEXT: [[Select_GPR_Using_CC_GPR:%[0-9]+]]:gpr = Select_GPR_Using_CC_GPR [[COPY]], $x0, 1, [[COPY1]], [[COPY2]] + ; CHECK-NEXT: $x10 = COPY [[Select_GPR_Using_CC_GPR]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = COPY $x12 + %3:gprb(s32) = G_SELECT %0, %1, %2 + $x10 = COPY %3(s32) + PseudoRET implicit $x10 + +... +--- +name: select_p0 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10, $x11, $x12 + + ; CHECK-LABEL: name: select_p0 + ; CHECK: liveins: $x10, $x11, $x12 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12 + ; CHECK-NEXT: [[Select_GPR_Using_CC_GPR:%[0-9]+]]:gpr = Select_GPR_Using_CC_GPR [[COPY]], $x0, 1, [[COPY1]], [[COPY2]] + ; CHECK-NEXT: $x10 = COPY [[Select_GPR_Using_CC_GPR]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(p0) = COPY $x11 + %2:gprb(p0) = COPY $x12 + %3:gprb(p0) = G_SELECT %0, %1, %2 + $x10 = COPY %3(p0) + PseudoRET implicit $x10 + +... diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/select-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/select-rv64.mir new file mode 100644 index 0000000000000..caa42f01c40ca --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/select-rv64.mir @@ -0,0 +1,55 @@ +# 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: select_s64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10, $x11, $x12 + + ; CHECK-LABEL: name: select_s64 + ; CHECK: liveins: $x10, $x11, $x12 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12 + ; CHECK-NEXT: [[Select_GPR_Using_CC_GPR:%[0-9]+]]:gpr = Select_GPR_Using_CC_GPR [[COPY]], $x0, 1, [[COPY1]], [[COPY2]] + ; CHECK-NEXT: $x10 = COPY [[Select_GPR_Using_CC_GPR]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = COPY $x12 + %3:gprb(s64) = G_SELECT %0, %1, %2 + $x10 = COPY %3(s64) + PseudoRET implicit $x10 + +... +--- +name: select_p0 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x10, $x11, $x12 + + ; CHECK-LABEL: name: select_p0 + ; CHECK: liveins: $x10, $x11, $x12 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12 + ; CHECK-NEXT: [[Select_GPR_Using_CC_GPR:%[0-9]+]]:gpr = Select_GPR_Using_CC_GPR [[COPY]], $x0, 1, [[COPY1]], [[COPY2]] + ; CHECK-NEXT: $x10 = COPY [[Select_GPR_Using_CC_GPR]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(p0) = COPY $x11 + %2:gprb(p0) = COPY $x12 + %3:gprb(p0) = G_SELECT %0, %1, %2 + $x10 = COPY %3(p0) + PseudoRET implicit $x10 + +...