diff --git a/llvm/lib/Target/RISCV/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/RISCVInstructionSelector.cpp --- a/llvm/lib/Target/RISCV/RISCVInstructionSelector.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstructionSelector.cpp @@ -14,8 +14,10 @@ #include "RISCVRegisterBankInfo.h" #include "RISCVSubtarget.h" #include "RISCVTargetMachine.h" +#include "Utils/RISCVMatInt.h" #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/Support/Debug.h" #define DEBUG_TYPE "riscv-isel" @@ -39,6 +41,11 @@ private: bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const; + bool isRegInGprBank(Register Reg, const MachineRegisterInfo &MRI) const; + const TargetRegisterClass *getRegClass(Register Reg, + const MachineRegisterInfo &MRI) const; + bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const; + bool selectConstant(MachineInstr &I, MachineRegisterInfo &MRI) const; const RISCVSubtarget &STI; const RISCVInstrInfo &TII; @@ -80,17 +87,101 @@ { } +bool RISCVInstructionSelector::isRegInGprBank( + Register Reg, const MachineRegisterInfo &MRI) const { + return RBI.getRegBank(Reg, MRI, TRI)->getID() == RISCV::GPRRegBankID; +} + +const TargetRegisterClass * +RISCVInstructionSelector::getRegClass(Register Reg, + const MachineRegisterInfo &MRI) const { + const LLT Ty = MRI.getType(Reg); + const unsigned Size = Ty.getSizeInBits(); + + if (isRegInGprBank(Reg, MRI)) { + assert((Ty.isScalar() || Ty.isPointer()) && + Size == (STI.is64Bit() ? 64 : 32) && + "Register class not available for LLT, register bank combination"); + return &RISCV::GPRRegClass; + } + + llvm_unreachable("Unsupported register bank."); +} +bool RISCVInstructionSelector::selectCopy(MachineInstr &I, + MachineRegisterInfo &MRI) const { + Register DstReg = I.getOperand(0).getReg(); + + if (Register::isPhysicalRegister(DstReg)) + return true; + + const TargetRegisterClass *RC = getRegClass(DstReg, MRI); + if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) { + LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) + << " operand\n"); + return false; + } + + return true; +} + +bool RISCVInstructionSelector::selectConstant(MachineInstr &I, + MachineRegisterInfo &MRI) const { + Register DstReg = I.getOperand(0).getReg(); + int64_t Val = I.getOperand(1).getCImm()->getSExtValue(); + MachineIRBuilder MIRBuilder(I); + + RISCVMatInt::InstSeq Seq; + RISCVMatInt::generateInstSeq(Val, STI.is64Bit(), Seq); + + // Source is X0 when used in the first instruction of the sequence. + Register SrcReg = RISCV::X0; + Register TmpReg; + for (RISCVMatInt::Inst &Inst : Seq) { + TmpReg = MRI.createVirtualRegister(&RISCV::GPRRegClass); + + MachineInstr *CurMI = + (Inst.Opc == RISCV::LUI + ? MIRBuilder.buildInstr(RISCV::LUI, {TmpReg}, {}) + : MIRBuilder.buildInstr(Inst.Opc, {TmpReg}, {SrcReg})) + .addImm(Inst.Imm); + + if (!constrainSelectedInstRegOperands(*CurMI, TII, TRI, RBI)) + return false; + + SrcReg = TmpReg; + } + + MIRBuilder.buildCopy({DstReg}, {TmpReg}); + return true; +} + bool RISCVInstructionSelector::select(MachineInstr &I) { + MachineBasicBlock &MBB = *I.getParent(); + MachineFunction &MF = *MBB.getParent(); + MachineRegisterInfo &MRI = MF.getRegInfo(); if (!isPreISelGenericOpcode(I.getOpcode())) { // Certain non-generic instructions also need some special handling. + if (I.isCopy()) + return selectCopy(I, MRI); + return true; } if (selectImpl(I, *CoverageInfo)) return true; - return false; + switch (I.getOpcode()) { + case TargetOpcode::G_CONSTANT: + if (!selectConstant(I, MRI)) + return false; + + break; + default: + return false; + } + I.eraseFromParent(); + return true; } namespace llvm { diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu32.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu32.mir @@ -0,0 +1,435 @@ +# 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 + +--- | + + define void @add_anyext() { entry: ret void } + define void @add_i8_signext() { entry: ret void } + define void @add_i8_zeroext() { entry: ret void } + define void @add_i16_signext() { entry: ret void } + define void @add_i16_zeroext() { entry: ret void } + + define void @add_i32() { entry: ret void } + define void @sub_i32() { entry: ret void } + define void @shl_i32() { entry: ret void } + define void @ashr_i32() { entry: ret void } + define void @lshr_i32() { entry: ret void } + define void @and_i32() { entry: ret void } + define void @or_i32() { entry: ret void } + define void @xor_i32() { entry: ret void } + + ; Split operations. + define void @add_i64() { entry: ret void } + define void @sub_i64() { entry: ret void } +... +--- +name: add_anyext +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: add_anyext + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV32I: $x10 = COPY [[ADD]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %2:gprb(s32) = COPY $x11 + %6:gprb(s32) = COPY %0(s32) + %7:gprb(s32) = COPY %2(s32) + %8:gprb(s32) = G_ADD %6, %7 + %5:gprb(s32) = COPY %8(s32) + $x10 = COPY %5(s32) + PseudoRET implicit $x10 + +... +--- +name: add_i8_signext +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: add_i8_signext + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV32I: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADD]], 24 + ; RV32I: [[SRAI:%[0-9]+]]:gpr = SRAI [[SLLI]], 24 + ; RV32I: $x10 = COPY [[SRAI]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %2:gprb(s32) = COPY $x11 + %6:gprb(s32) = COPY %0(s32) + %7:gprb(s32) = COPY %2(s32) + %8:gprb(s32) = G_ADD %6, %7 + %9:gprb(s32) = COPY %8(s32) + %11:gprb(s32) = G_CONSTANT i32 24 + %10:gprb(s32) = G_SHL %9, %11(s32) + %5:gprb(s32) = G_ASHR %10, %11(s32) + $x10 = COPY %5(s32) + PseudoRET implicit $x10 + +... +--- +name: add_i8_zeroext +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: add_i8_zeroext + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV32I: [[ANDI:%[0-9]+]]:gpr = ANDI [[ADD]], 255 + ; RV32I: $x10 = COPY [[ANDI]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %2:gprb(s32) = COPY $x11 + %6:gprb(s32) = COPY %0(s32) + %7:gprb(s32) = COPY %2(s32) + %8:gprb(s32) = G_ADD %6, %7 + %9:gprb(s32) = G_CONSTANT i32 255 + %10:gprb(s32) = COPY %8(s32) + %5:gprb(s32) = G_AND %10, %9 + $x10 = COPY %5(s32) + PseudoRET implicit $x10 + +... +--- +name: add_i16_signext +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: add_i16_signext + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV32I: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADD]], 16 + ; RV32I: [[SRAI:%[0-9]+]]:gpr = SRAI [[SLLI]], 16 + ; RV32I: $x10 = COPY [[SRAI]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %2:gprb(s32) = COPY $x11 + %6:gprb(s32) = COPY %0(s32) + %7:gprb(s32) = COPY %2(s32) + %8:gprb(s32) = G_ADD %6, %7 + %9:gprb(s32) = COPY %8(s32) + %11:gprb(s32) = G_CONSTANT i32 16 + %10:gprb(s32) = G_SHL %9, %11(s32) + %5:gprb(s32) = G_ASHR %10, %11(s32) + $x10 = COPY %5(s32) + PseudoRET implicit $x10 + +... +--- +name: add_i16_zeroext +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: add_i16_zeroext + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV32I: [[LUI:%[0-9]+]]:gpr = LUI 16 + ; RV32I: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], -1 + ; RV32I: [[AND:%[0-9]+]]:gpr = AND [[ADD]], [[ADDI]] + ; RV32I: $x10 = COPY [[AND]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %2:gprb(s32) = COPY $x11 + %6:gprb(s32) = COPY %0(s32) + %7:gprb(s32) = COPY %2(s32) + %8:gprb(s32) = G_ADD %6, %7 + %9:gprb(s32) = G_CONSTANT i32 65535 + %10:gprb(s32) = COPY %8(s32) + %5:gprb(s32) = G_AND %10, %9 + $x10 = COPY %5(s32) + PseudoRET implicit $x10 + +... +--- +name: add_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: add_i32 + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV32I: $x10 = COPY [[ADD]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_ADD %0, %1 + $x10 = COPY %2(s32) + PseudoRET implicit $x10 + +... +--- +name: sub_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: sub_i32 + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[SUB:%[0-9]+]]:gpr = SUB [[COPY]], [[COPY1]] + ; RV32I: $x10 = COPY [[SUB]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_SUB %0, %1 + $x10 = COPY %2(s32) + PseudoRET implicit $x10 + +... +--- +name: shl_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: shl_i32 + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[SLL:%[0-9]+]]:gpr = SLL [[COPY]], [[COPY1]] + ; RV32I: $x10 = COPY [[SLL]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_SHL %0, %1 + $x10 = COPY %2(s32) + PseudoRET implicit $x10 + +... +--- +name: ashr_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: ashr_i32 + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[SRA:%[0-9]+]]:gpr = SRA [[COPY]], [[COPY1]] + ; RV32I: $x10 = COPY [[SRA]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_ASHR %0, %1 + $x10 = COPY %2(s32) + PseudoRET implicit $x10 + +... +--- +name: lshr_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: lshr_i32 + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[SRL:%[0-9]+]]:gpr = SRL [[COPY]], [[COPY1]] + ; RV32I: $x10 = COPY [[SRL]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_LSHR %0, %1 + $x10 = COPY %2(s32) + PseudoRET implicit $x10 + +... +--- +name: and_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: and_i32 + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[AND:%[0-9]+]]:gpr = AND [[COPY]], [[COPY1]] + ; RV32I: $x10 = COPY [[AND]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_AND %0, %1 + $x10 = COPY %2(s32) + PseudoRET implicit $x10 + +... +--- +name: or_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: or_i32 + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[OR:%[0-9]+]]:gpr = OR [[COPY]], [[COPY1]] + ; RV32I: $x10 = COPY [[OR]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_OR %0, %1 + $x10 = COPY %2(s32) + PseudoRET implicit $x10 + +... +--- +name: xor_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: xor_i32 + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[XOR:%[0-9]+]]:gpr = XOR [[COPY]], [[COPY1]] + ; RV32I: $x10 = COPY [[XOR]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_XOR %0, %1 + $x10 = COPY %2(s32) + PseudoRET implicit $x10 + +... +--- +name: add_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11, $x12, $x13 + + ; RV32I-LABEL: name: add_i64 + ; RV32I: liveins: $x10, $x11, $x12, $x13 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[COPY2:%[0-9]+]]:gpr = COPY $x12 + ; RV32I: [[COPY3:%[0-9]+]]:gpr = COPY $x13 + ; RV32I: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY2]] + ; RV32I: [[SLTU:%[0-9]+]]:gpr = SLTU [[ADD]], [[COPY2]] + ; RV32I: [[ADD1:%[0-9]+]]:gpr = ADD [[COPY1]], [[COPY3]] + ; RV32I: [[ANDI:%[0-9]+]]:gpr = ANDI [[SLTU]], 1 + ; RV32I: [[ADD2:%[0-9]+]]:gpr = ADD [[ADD1]], [[ANDI]] + ; RV32I: $x10 = COPY [[ADD]] + ; RV32I: $x11 = COPY [[ADD2]] + ; RV32I: PseudoRET implicit $x10, implicit $x11 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = COPY $x12 + %3:gprb(s32) = COPY $x13 + %13:gprb(s32) = G_ADD %0, %2 + %19:gprb(s32) = G_ICMP intpred(ult), %13(s32), %2 + %17:gprb(s32) = G_ADD %1, %3 + %20:gprb(s32) = G_CONSTANT i32 1 + %21:gprb(s32) = COPY %19(s32) + %18:gprb(s32) = G_AND %21, %20 + %15:gprb(s32) = G_ADD %17, %18 + $x10 = COPY %13(s32) + $x11 = COPY %15(s32) + PseudoRET implicit $x10, implicit $x11 + +... +--- +name: sub_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11, $x12, $x13 + + ; RV32I-LABEL: name: sub_i64 + ; RV32I: liveins: $x10, $x11, $x12, $x13 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[COPY2:%[0-9]+]]:gpr = COPY $x12 + ; RV32I: [[COPY3:%[0-9]+]]:gpr = COPY $x13 + ; RV32I: [[SUB:%[0-9]+]]:gpr = SUB [[COPY]], [[COPY2]] + ; RV32I: [[SLTU:%[0-9]+]]:gpr = SLTU [[COPY]], [[COPY2]] + ; RV32I: [[SUB1:%[0-9]+]]:gpr = SUB [[COPY1]], [[COPY3]] + ; RV32I: [[ANDI:%[0-9]+]]:gpr = ANDI [[SLTU]], 1 + ; RV32I: [[SUB2:%[0-9]+]]:gpr = SUB [[SUB1]], [[ANDI]] + ; RV32I: $x10 = COPY [[SUB]] + ; RV32I: $x11 = COPY [[SUB2]] + ; RV32I: PseudoRET implicit $x10, implicit $x11 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = COPY $x12 + %3:gprb(s32) = COPY $x13 + %13:gprb(s32) = G_SUB %0, %2 + %21:gprb(s32) = G_ICMP intpred(ult), %0(s32), %2 + %17:gprb(s32) = G_SUB %1, %3 + %22:gprb(s32) = G_CONSTANT i32 1 + %23:gprb(s32) = COPY %21(s32) + %18:gprb(s32) = G_AND %23, %22 + %15:gprb(s32) = G_SUB %17, %18 + $x10 = COPY %13(s32) + $x11 = COPY %15(s32) + PseudoRET implicit $x10, implicit $x11 + +... diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu32_m.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu32_m.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu32_m.mir @@ -0,0 +1,169 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=riscv32 -mattr=+m -run-pass=instruction-select -simplify-mir -verify-machineinstrs %s -o - \ +# RUN: | FileCheck -check-prefix=RV32I %s + +--- | + + define void @mul_i32() { entry: ret void } + define void @sdiv_i32() { entry: ret void } + define void @srem_i32() { entry: ret void } + define void @udiv_i32() { entry: ret void } + define void @urem_i32() { entry: ret void } + + ; Split operations. + define void @mul_i64() { entry: ret void } +... +--- +name: mul_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: mul_i32 + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[MUL:%[0-9]+]]:gpr = MUL [[COPY]], [[COPY1]] + ; RV32I: $x10 = COPY [[MUL]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_MUL %0, %1 + $x10 = COPY %2(s32) + PseudoRET implicit $x10 + +... +--- +name: sdiv_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: sdiv_i32 + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[DIV:%[0-9]+]]:gpr = DIV [[COPY]], [[COPY1]] + ; RV32I: $x10 = COPY [[DIV]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_SDIV %0, %1 + $x10 = COPY %2(s32) + PseudoRET implicit $x10 + +... +--- +name: srem_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: srem_i32 + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[REM:%[0-9]+]]:gpr = REM [[COPY]], [[COPY1]] + ; RV32I: $x10 = COPY [[REM]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_SREM %0, %1 + $x10 = COPY %2(s32) + PseudoRET implicit $x10 + +... +--- +name: udiv_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: udiv_i32 + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[DIVU:%[0-9]+]]:gpr = DIVU [[COPY]], [[COPY1]] + ; RV32I: $x10 = COPY [[DIVU]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_UDIV %0, %1 + $x10 = COPY %2(s32) + PseudoRET implicit $x10 + +... +--- +name: urem_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV32I-LABEL: name: urem_i32 + ; RV32I: liveins: $x10, $x11 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[REMU:%[0-9]+]]:gpr = REMU [[COPY]], [[COPY1]] + ; RV32I: $x10 = COPY [[REMU]] + ; RV32I: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_UREM %0, %1 + $x10 = COPY %2(s32) + PseudoRET implicit $x10 + +... +--- +name: mul_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11, $x12, $x13 + + ; RV32I-LABEL: name: mul_i64 + ; RV32I: liveins: $x10, $x11, $x12, $x13 + ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I: [[COPY2:%[0-9]+]]:gpr = COPY $x12 + ; RV32I: [[COPY3:%[0-9]+]]:gpr = COPY $x13 + ; RV32I: [[MUL:%[0-9]+]]:gpr = MUL [[COPY]], [[COPY2]] + ; RV32I: [[MUL1:%[0-9]+]]:gpr = MUL [[COPY1]], [[COPY2]] + ; RV32I: [[MUL2:%[0-9]+]]:gpr = MUL [[COPY]], [[COPY3]] + ; RV32I: [[MULHU:%[0-9]+]]:gpr = MULHU [[COPY]], [[COPY2]] + ; RV32I: [[ADD:%[0-9]+]]:gpr = ADD [[MUL1]], [[MUL2]] + ; RV32I: [[ADD1:%[0-9]+]]:gpr = ADD [[ADD]], [[MULHU]] + ; RV32I: $x10 = COPY [[MUL]] + ; RV32I: $x11 = COPY [[ADD1]] + ; RV32I: PseudoRET implicit $x10, implicit $x11 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = COPY $x12 + %3:gprb(s32) = COPY $x13 + %13:gprb(s32) = G_MUL %0, %2 + %14:gprb(s32) = G_MUL %1, %2 + %15:gprb(s32) = G_MUL %0, %3 + %16:gprb(s32) = G_UMULH %0, %2 + %17:gprb(s32) = G_ADD %14, %15 + %18:gprb(s32) = G_ADD %17, %16 + $x10 = COPY %13(s32) + $x11 = COPY %18(s32) + PseudoRET implicit $x10, implicit $x11 + +... diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu64.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu64.mir @@ -0,0 +1,572 @@ +# 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 + +--- | + + define void @add_anyext() { entry: ret void } + define void @add_i8_signext() { entry: ret void } + define void @add_i8_zeroext() { entry: ret void } + define void @add_i16_signext() { entry: ret void } + define void @add_i16_zeroext() { entry: ret void } + + ; Special case for i32 - single word operations are used. + define void @add_i32() { entry: ret void } + define void @sub_i32() { entry: ret void } + define void @shl_i32() { entry: ret void } + define void @ashr_i32() { entry: ret void } + define void @lshr_i32() { entry: ret void } + + define void @add_i64() { entry: ret void } + define void @sub_i64() { entry: ret void } + define void @shl_i64() { entry: ret void } + define void @ashr_i64() { entry: ret void } + define void @lshr_i64() { entry: ret void } + define void @and_i64() { entry: ret void } + define void @or_i64() { entry: ret void } + define void @xor_i64() { entry: ret void } + + ; Split operations. + define void @add_i128() { entry: ret void } + define void @sub_i128() { entry: ret void } +... +--- +name: add_anyext +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: add_anyext + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[ADD]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %2:gprb(s64) = COPY $x11 + %6:gprb(s64) = COPY %0(s64) + %7:gprb(s64) = COPY %2(s64) + %8:gprb(s64) = G_ADD %6, %7 + %5:gprb(s64) = COPY %8(s64) + $x10 = COPY %5(s64) + PseudoRET implicit $x10 + +... +--- +name: add_i8_signext +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: add_i8_signext + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV64I: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADD]], 56 + ; RV64I: [[SRAI:%[0-9]+]]:gpr = SRAI [[SLLI]], 56 + ; RV64I: $x10 = COPY [[SRAI]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %2:gprb(s64) = COPY $x11 + %6:gprb(s64) = COPY %0(s64) + %7:gprb(s64) = COPY %2(s64) + %8:gprb(s64) = G_ADD %6, %7 + %9:gprb(s64) = COPY %8(s64) + %11:gprb(s64) = G_CONSTANT i64 56 + %10:gprb(s64) = G_SHL %9, %11(s64) + %5:gprb(s64) = G_ASHR %10, %11(s64) + $x10 = COPY %5(s64) + PseudoRET implicit $x10 + +... +--- +name: add_i8_zeroext +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: add_i8_zeroext + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV64I: [[ANDI:%[0-9]+]]:gpr = ANDI [[ADD]], 255 + ; RV64I: $x10 = COPY [[ANDI]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %2:gprb(s64) = COPY $x11 + %6:gprb(s64) = COPY %0(s64) + %7:gprb(s64) = COPY %2(s64) + %8:gprb(s64) = G_ADD %6, %7 + %9:gprb(s64) = G_CONSTANT i64 255 + %10:gprb(s64) = COPY %8(s64) + %5:gprb(s64) = G_AND %10, %9 + $x10 = COPY %5(s64) + PseudoRET implicit $x10 + +... +--- +name: add_i16_signext +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: add_i16_signext + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV64I: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADD]], 48 + ; RV64I: [[SRAI:%[0-9]+]]:gpr = SRAI [[SLLI]], 48 + ; RV64I: $x10 = COPY [[SRAI]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %2:gprb(s64) = COPY $x11 + %6:gprb(s64) = COPY %0(s64) + %7:gprb(s64) = COPY %2(s64) + %8:gprb(s64) = G_ADD %6, %7 + %9:gprb(s64) = COPY %8(s64) + %11:gprb(s64) = G_CONSTANT i64 48 + %10:gprb(s64) = G_SHL %9, %11(s64) + %5:gprb(s64) = G_ASHR %10, %11(s64) + $x10 = COPY %5(s64) + PseudoRET implicit $x10 + +... +--- +name: add_i16_zeroext +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: add_i16_zeroext + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV64I: [[LUI:%[0-9]+]]:gpr = LUI 16 + ; RV64I: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[LUI]], -1 + ; RV64I: [[AND:%[0-9]+]]:gpr = AND [[ADD]], [[ADDIW]] + ; RV64I: $x10 = COPY [[AND]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %2:gprb(s64) = COPY $x11 + %6:gprb(s64) = COPY %0(s64) + %7:gprb(s64) = COPY %2(s64) + %8:gprb(s64) = G_ADD %6, %7 + %9:gprb(s64) = G_CONSTANT i64 65535 + %10:gprb(s64) = COPY %8(s64) + %5:gprb(s64) = G_AND %10, %9 + $x10 = COPY %5(s64) + PseudoRET implicit $x10 + +... +--- +name: add_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: add_i32 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[ADDW:%[0-9]+]]:gpr = ADDW [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[ADDW]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %2:gprb(s64) = COPY $x11 + %6:gpr(s64) = COPY %0(s64) + %7:gpr(s64) = COPY %2(s64) + %8:gpr(s64) = ADDW %6(s64), %7(s64) + %5:gprb(s64) = COPY %8(s64) + $x10 = COPY %5(s64) + PseudoRET implicit $x10 + +... +--- +name: sub_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: sub_i32 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[SUBW:%[0-9]+]]:gpr = SUBW [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[SUBW]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %2:gprb(s64) = COPY $x11 + %6:gpr(s64) = COPY %0(s64) + %7:gpr(s64) = COPY %2(s64) + %8:gpr(s64) = SUBW %6(s64), %7(s64) + %5:gprb(s64) = COPY %8(s64) + $x10 = COPY %5(s64) + PseudoRET implicit $x10 + +... +--- +name: shl_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: shl_i32 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[SLLW:%[0-9]+]]:gpr = SLLW [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[SLLW]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %2:gprb(s64) = COPY $x11 + %6:gpr(s64) = COPY %0(s64) + %7:gpr(s64) = COPY %2(s64) + %8:gpr(s64) = SLLW %6(s64), %7(s64) + %5:gprb(s64) = COPY %8(s64) + $x10 = COPY %5(s64) + PseudoRET implicit $x10 + +... +--- +name: ashr_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: ashr_i32 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[SRAW:%[0-9]+]]:gpr = SRAW [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[SRAW]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %2:gprb(s64) = COPY $x11 + %6:gpr(s64) = COPY %0(s64) + %7:gpr(s64) = COPY %2(s64) + %8:gpr(s64) = SRAW %6(s64), %7(s64) + %5:gprb(s64) = COPY %8(s64) + $x10 = COPY %5(s64) + PseudoRET implicit $x10 + +... +--- +name: lshr_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: lshr_i32 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[SRLW:%[0-9]+]]:gpr = SRLW [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[SRLW]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %2:gprb(s64) = COPY $x11 + %6:gpr(s64) = COPY %0(s64) + %7:gpr(s64) = COPY %2(s64) + %8:gpr(s64) = SRLW %6(s64), %7(s64) + %5:gprb(s64) = COPY %8(s64) + $x10 = COPY %5(s64) + PseudoRET implicit $x10 + +... +--- +name: add_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: add_i64 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[ADD]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_ADD %0, %1 + $x10 = COPY %2(s64) + PseudoRET implicit $x10 + +... +--- +name: sub_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: sub_i64 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[SUB:%[0-9]+]]:gpr = SUB [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[SUB]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_SUB %0, %1 + $x10 = COPY %2(s64) + PseudoRET implicit $x10 + +... +--- +name: shl_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: shl_i64 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[SLL:%[0-9]+]]:gpr = SLL [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[SLL]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_SHL %0, %1 + $x10 = COPY %2(s64) + PseudoRET implicit $x10 + +... +--- +name: ashr_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: ashr_i64 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[SRA:%[0-9]+]]:gpr = SRA [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[SRA]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_ASHR %0, %1 + $x10 = COPY %2(s64) + PseudoRET implicit $x10 + +... +--- +name: lshr_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: lshr_i64 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[SRL:%[0-9]+]]:gpr = SRL [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[SRL]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_LSHR %0, %1 + $x10 = COPY %2(s64) + PseudoRET implicit $x10 + +... +--- +name: and_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: and_i64 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[AND:%[0-9]+]]:gpr = AND [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[AND]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_AND %0, %1 + $x10 = COPY %2(s64) + PseudoRET implicit $x10 + +... +--- +name: or_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: or_i64 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[OR:%[0-9]+]]:gpr = OR [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[OR]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_OR %0, %1 + $x10 = COPY %2(s64) + PseudoRET implicit $x10 + +... +--- +name: xor_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: xor_i64 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[XOR:%[0-9]+]]:gpr = XOR [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[XOR]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_XOR %0, %1 + $x10 = COPY %2(s64) + PseudoRET implicit $x10 + +... +--- +name: add_i128 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11, $x12, $x13 + + ; RV64I-LABEL: name: add_i128 + ; RV64I: liveins: $x10, $x11, $x12, $x13 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[COPY2:%[0-9]+]]:gpr = COPY $x12 + ; RV64I: [[COPY3:%[0-9]+]]:gpr = COPY $x13 + ; RV64I: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY2]] + ; RV64I: [[SLTU:%[0-9]+]]:gpr = SLTU [[ADD]], [[COPY2]] + ; RV64I: [[ADD1:%[0-9]+]]:gpr = ADD [[COPY1]], [[COPY3]] + ; RV64I: [[ANDI:%[0-9]+]]:gpr = ANDI [[SLTU]], 1 + ; RV64I: [[ADD2:%[0-9]+]]:gpr = ADD [[ADD1]], [[ANDI]] + ; RV64I: $x10 = COPY [[ADD]] + ; RV64I: $x11 = COPY [[ADD2]] + ; RV64I: PseudoRET implicit $x10, implicit $x11 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = COPY $x12 + %3:gprb(s64) = COPY $x13 + %13:gprb(s64) = G_ADD %0, %2 + %19:gprb(s64) = G_ICMP intpred(ult), %13(s64), %2 + %17:gprb(s64) = G_ADD %1, %3 + %20:gprb(s64) = G_CONSTANT i64 1 + %21:gprb(s64) = COPY %19(s64) + %18:gprb(s64) = G_AND %21, %20 + %15:gprb(s64) = G_ADD %17, %18 + $x10 = COPY %13(s64) + $x11 = COPY %15(s64) + PseudoRET implicit $x10, implicit $x11 + +... +--- +name: sub_i128 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11, $x12, $x13 + + ; RV64I-LABEL: name: sub_i128 + ; RV64I: liveins: $x10, $x11, $x12, $x13 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[COPY2:%[0-9]+]]:gpr = COPY $x12 + ; RV64I: [[COPY3:%[0-9]+]]:gpr = COPY $x13 + ; RV64I: [[SUB:%[0-9]+]]:gpr = SUB [[COPY]], [[COPY2]] + ; RV64I: [[SLTU:%[0-9]+]]:gpr = SLTU [[COPY]], [[COPY2]] + ; RV64I: [[SUB1:%[0-9]+]]:gpr = SUB [[COPY1]], [[COPY3]] + ; RV64I: [[ANDI:%[0-9]+]]:gpr = ANDI [[SLTU]], 1 + ; RV64I: [[SUB2:%[0-9]+]]:gpr = SUB [[SUB1]], [[ANDI]] + ; RV64I: $x10 = COPY [[SUB]] + ; RV64I: $x11 = COPY [[SUB2]] + ; RV64I: PseudoRET implicit $x10, implicit $x11 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = COPY $x12 + %3:gprb(s64) = COPY $x13 + %13:gprb(s64) = G_SUB %0, %2 + %21:gprb(s64) = G_ICMP intpred(ult), %0(s64), %2 + %17:gprb(s64) = G_SUB %1, %3 + %22:gprb(s64) = G_CONSTANT i64 1 + %23:gprb(s64) = COPY %21(s64) + %18:gprb(s64) = G_AND %23, %22 + %15:gprb(s64) = G_SUB %17, %18 + $x10 = COPY %13(s64) + $x11 = COPY %15(s64) + PseudoRET implicit $x10, implicit $x11 + +... diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu64_m.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu64_m.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/alu64_m.mir @@ -0,0 +1,306 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=riscv64 -mattr=+m -run-pass=instruction-select -simplify-mir -verify-machineinstrs %s -o - \ +# RUN: | FileCheck -check-prefix=RV64I %s + +--- | + + ; Special case for i32 - single word operations are used. + define void @mul_i32() { entry: ret void } + define void @sdiv_i32() { entry: ret void } + define void @srem_i32() { entry: ret void } + define void @udiv_i32() { entry: ret void } + define void @urem_i32() { entry: ret void } + + define void @mul_i64() { entry: ret void } + define void @sdiv_i64() { entry: ret void } + define void @srem_i64() { entry: ret void } + define void @udiv_i64() { entry: ret void } + define void @urem_i64() { entry: ret void } + + ; Split operations. + define void @mul_i128() { entry: ret void } +... +--- +name: mul_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: mul_i32 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[MULW:%[0-9]+]]:gpr = MULW [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[MULW]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %2:gprb(s64) = COPY $x11 + %6:gpr(s64) = COPY %0(s64) + %7:gpr(s64) = COPY %2(s64) + %8:gpr(s64) = MULW %6(s64), %7(s64) + %5:gprb(s64) = COPY %8(s64) + $x10 = COPY %5(s64) + PseudoRET implicit $x10 + +... +--- +name: sdiv_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: sdiv_i32 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[DIVW:%[0-9]+]]:gpr = DIVW [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[DIVW]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %2:gprb(s64) = COPY $x11 + %6:gpr(s64) = COPY %0(s64) + %7:gpr(s64) = COPY %2(s64) + %8:gpr(s64) = DIVW %6(s64), %7(s64) + %5:gprb(s64) = COPY %8(s64) + $x10 = COPY %5(s64) + PseudoRET implicit $x10 + +... +--- +name: srem_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: srem_i32 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[REMW:%[0-9]+]]:gpr = REMW [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[REMW]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %2:gprb(s64) = COPY $x11 + %6:gpr(s64) = COPY %0(s64) + %7:gpr(s64) = COPY %2(s64) + %8:gpr(s64) = REMW %6(s64), %7(s64) + %5:gprb(s64) = COPY %8(s64) + $x10 = COPY %5(s64) + PseudoRET implicit $x10 + +... +--- +name: udiv_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: udiv_i32 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[DIVUW:%[0-9]+]]:gpr = DIVUW [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[DIVUW]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %2:gprb(s64) = COPY $x11 + %6:gpr(s64) = COPY %0(s64) + %7:gpr(s64) = COPY %2(s64) + %8:gpr(s64) = DIVUW %6(s64), %7(s64) + %5:gprb(s64) = COPY %8(s64) + $x10 = COPY %5(s64) + PseudoRET implicit $x10 + +... +--- +name: urem_i32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: urem_i32 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[REMUW:%[0-9]+]]:gpr = REMUW [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[REMUW]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %2:gprb(s64) = COPY $x11 + %6:gpr(s64) = COPY %0(s64) + %7:gpr(s64) = COPY %2(s64) + %8:gpr(s64) = REMUW %6(s64), %7(s64) + %5:gprb(s64) = COPY %8(s64) + $x10 = COPY %5(s64) + PseudoRET implicit $x10 + +... +--- +name: mul_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: mul_i64 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[MUL:%[0-9]+]]:gpr = MUL [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[MUL]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_MUL %0, %1 + $x10 = COPY %2(s64) + PseudoRET implicit $x10 + +... +--- +name: sdiv_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: sdiv_i64 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[DIV:%[0-9]+]]:gpr = DIV [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[DIV]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_SDIV %0, %1 + $x10 = COPY %2(s64) + PseudoRET implicit $x10 + +... +--- +name: srem_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: srem_i64 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[REM:%[0-9]+]]:gpr = REM [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[REM]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_SREM %0, %1 + $x10 = COPY %2(s64) + PseudoRET implicit $x10 + +... +--- +name: udiv_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: udiv_i64 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[DIVU:%[0-9]+]]:gpr = DIVU [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[DIVU]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_UDIV %0, %1 + $x10 = COPY %2(s64) + PseudoRET implicit $x10 + +... +--- +name: urem_i64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11 + + ; RV64I-LABEL: name: urem_i64 + ; RV64I: liveins: $x10, $x11 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[REMU:%[0-9]+]]:gpr = REMU [[COPY]], [[COPY1]] + ; RV64I: $x10 = COPY [[REMU]] + ; RV64I: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_UREM %0, %1 + $x10 = COPY %2(s64) + PseudoRET implicit $x10 + +... +--- +name: mul_i128 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10, $x11, $x12, $x13 + + ; RV64I-LABEL: name: mul_i128 + ; RV64I: liveins: $x10, $x11, $x12, $x13 + ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I: [[COPY2:%[0-9]+]]:gpr = COPY $x12 + ; RV64I: [[COPY3:%[0-9]+]]:gpr = COPY $x13 + ; RV64I: [[MUL:%[0-9]+]]:gpr = MUL [[COPY]], [[COPY2]] + ; RV64I: [[MUL1:%[0-9]+]]:gpr = MUL [[COPY1]], [[COPY2]] + ; RV64I: [[MUL2:%[0-9]+]]:gpr = MUL [[COPY]], [[COPY3]] + ; RV64I: [[MULHU:%[0-9]+]]:gpr = MULHU [[COPY]], [[COPY2]] + ; RV64I: [[ADD:%[0-9]+]]:gpr = ADD [[MUL1]], [[MUL2]] + ; RV64I: [[ADD1:%[0-9]+]]:gpr = ADD [[ADD]], [[MULHU]] + ; RV64I: $x10 = COPY [[MUL]] + ; RV64I: $x11 = COPY [[ADD1]] + ; RV64I: PseudoRET implicit $x10, implicit $x11 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = COPY $x12 + %3:gprb(s64) = COPY $x13 + %13:gprb(s64) = G_MUL %0, %2 + %14:gprb(s64) = G_MUL %1, %2 + %15:gprb(s64) = G_MUL %0, %3 + %16:gprb(s64) = G_UMULH %0, %2 + %17:gprb(s64) = G_ADD %14, %15 + %18:gprb(s64) = G_ADD %17, %16 + $x10 = COPY %13(s64) + $x11 = COPY %18(s64) + PseudoRET implicit $x10, implicit $x11 + +...