diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt --- a/llvm/lib/Target/RISCV/CMakeLists.txt +++ b/llvm/lib/Target/RISCV/CMakeLists.txt @@ -7,7 +7,6 @@ tablegen(LLVM RISCVGenCompressInstEmitter.inc -gen-compress-inst-emitter) tablegen(LLVM RISCVGenDAGISel.inc -gen-dag-isel) tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler) -tablegen(LLVM RISCVGenGlobalISel.inc -gen-global-isel) tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info) tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter) tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering) @@ -16,6 +15,9 @@ tablegen(LLVM RISCVGenSearchableTables.inc -gen-searchable-tables) tablegen(LLVM RISCVGenSubtargetInfo.inc -gen-subtarget) +set(LLVM_TARGET_DEFINITIONS RISCVGISel.td) +tablegen(LLVM RISCVGenGlobalISel.inc -gen-global-isel) + add_public_tablegen_target(RISCVCommonTableGen) add_llvm_target(RISCVCodeGen 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" @@ -39,7 +41,15 @@ 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 &I, MachineRegisterInfo &MRI) const; + bool selectConstant(MachineInstr &I, MachineRegisterInfo &MRI) const; + + ComplexRendererFns selectS32ShiftMask(MachineOperand &Root) const; const RISCVSubtarget &STI; const RISCVInstrInfo &TII; @@ -80,17 +90,146 @@ { } +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 &I, + MachineRegisterInfo &MRI) const { + Register DstReg = I.getOperand(0).getReg(); + Register SrcReg = I.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(I.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(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.getFeatureBits()); + + // 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; + switch (Inst.getOpndKind()) { + case RISCVMatInt::Imm: + CurMI = MIRBuilder.buildInstr(Inst.getOpcode(), {TmpReg}, {}) + .addImm(Inst.getImm()); + break; + case RISCVMatInt::RegX0: + CurMI = MIRBuilder.buildInstr(Inst.getOpcode(), {TmpReg}, {SrcReg}) + .addReg(RISCV::X0) + .addImm(Inst.getImm()); + break; + case RISCVMatInt::RegReg: + CurMI = + MIRBuilder.buildInstr(Inst.getOpcode(), {TmpReg}, {SrcReg, SrcReg}) + .addImm(Inst.getImm()); + break; + case RISCVMatInt::RegImm: + CurMI = MIRBuilder.buildInstr(Inst.getOpcode(), {TmpReg}, {SrcReg}) + .addImm(Inst.getImm()); + break; + } + + if (!constrainSelectedInstRegOperands(*CurMI, TII, TRI, RBI)) + return false; + + SrcReg = TmpReg; + } + + MIRBuilder.buildCopy({DstReg}, {TmpReg}); + if (!RBI.constrainGenericRegister(DstReg, RISCV::GPRRegClass, MRI)) + return false; + + return true; +} + +InstructionSelector::ComplexRendererFns +RISCVInstructionSelector::selectS32ShiftMask(MachineOperand &Root) const { + // TODO: Also check if we are seeing the result of an AND operation which + // could be bypassed since we only check the lower log2(xlen) bits. + return {{ + [=](MachineInstrBuilder &MIB) { MIB.addReg(Root.getReg()); }, + [=](MachineInstrBuilder &MIB) { MIB.addImm(0); } // src_mods + }}; +} + 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; + case TargetOpcode::G_ANYEXT: + case TargetOpcode::G_TRUNC: + I.setDesc(TII.get(TargetOpcode::COPY)); + return true; + default: + return false; + } + I.eraseFromParent(); + return true; } namespace llvm { diff --git a/llvm/lib/Target/RISCV/RISCVGISel.td b/llvm/lib/Target/RISCV/RISCVGISel.td new file mode 100644 --- /dev/null +++ b/llvm/lib/Target/RISCV/RISCVGISel.td @@ -0,0 +1,49 @@ +//===-- RISCVGIsel.td - RISCV GlobalISel Patterns ----------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +/// \file +/// This file contains patterns that are relevant to GlobalISel, including +/// GIComplexOperandMatcher definitions for equivalent SelectionDAG +/// ComplexPatterns. +// +//===----------------------------------------------------------------------===// + +include "RISCV.td" + +// FIXME: This is labelled as handling 's32', however the ComplexPattern it +// refers to handles both i32 and i64 based on the HwMode. Currently this LLT +// parameter appears to be ignored so this pattern works for both, however we +// should add a LowLevelTypeByHwMode, and use that to define our XLenLLT instead +// here. +def s32ShiftMaskGI : + GIComplexOperandMatcher, + GIComplexPatternEquiv; + +//// Match a 32-bit -> 64-bit sign extend of an operation, such that it can be +//// replaced with an RV64 sign extending "W" instruction. +//class PatSExtOpWGI +// : Pat<(i64 (sra (shl (OpNode GPR:$rs1, GPR:$rs2), (i64 32)), (i64 32))), +// (Inst GPR:$rs1, GPR:$rs2)>; +// +//def : PatSExtOpWGI; +//def : PatSExtOpWGI; +//def : PatSExtOpWGI; +//def : PatSExtOpWGI; +//def : PatSExtOpWGI; +// +//// Match a 32-bit -> 64-bit zero extend of an operation, such that it can be +//// replaced with an RV64 zero extending "W" instruction. +//class PatZExtOpWGI +// : Pat<(i64 (and (OpNode GPR:$rs1, GPR:$rs2), (i64 0xffffffff))), +// (Inst GPR:$rs1, GPR:$rs2)>; +// +//def : PatZExtOpWGI; +//def : PatZExtOpWGI; +//def : PatZExtOpWGI; +//def : PatZExtOpWGI; +//def : PatZExtOpWGI; diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip.ll b/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip.ll @@ -0,0 +1,379 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+m -global-isel -verify-machineinstrs < %s \ +; RUN: | FileCheck %s --check-prefix=RV32IM +; RUN: llc -mtriple=riscv64 -mattr=+m -global-isel -verify-machineinstrs < %s \ +; RUN: | FileCheck %s --check-prefix=RV64IM + +; Extends to 32 bits exhaustively tested for add only. + +define i8 @add_i8(i8 %a, i8 %b) { +; RV32IM-LABEL: add_i8: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: add a0, a0, a1 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: add_i8: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: add a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = add i8 %a, %b + ret i8 %0 +} + +define i32 @add_i8_signext_i32(i8 %a, i8 %b) { +; RV32IM-LABEL: add_i8_signext_i32: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: slli a0, a0, 24 +; RV32IM-NEXT: srai a0, a0, 24 +; RV32IM-NEXT: slli a1, a1, 24 +; RV32IM-NEXT: srai a1, a1, 24 +; RV32IM-NEXT: add a0, a0, a1 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: add_i8_signext_i32: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: slli a0, a0, 24 +; RV64IM-NEXT: srai a0, a0, 24 +; RV64IM-NEXT: slli a1, a1, 24 +; RV64IM-NEXT: srai a1, a1, 24 +; RV64IM-NEXT: add a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = sext i8 %a to i32 + %1 = sext i8 %b to i32 + %2 = add i32 %0, %1 + ret i32 %2 +} + +define i32 @add_i8_zeroext_i32(i8 %a, i8 %b) { +; RV32IM-LABEL: add_i8_zeroext_i32: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: andi a0, a0, 255 +; RV32IM-NEXT: andi a1, a1, 255 +; RV32IM-NEXT: add a0, a0, a1 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: add_i8_zeroext_i32: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: andi a0, a0, 255 +; RV64IM-NEXT: andi a1, a1, 255 +; RV64IM-NEXT: add a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = zext i8 %a to i32 + %1 = zext i8 %b to i32 + %2 = add i32 %0, %1 + ret i32 %2 +} + +; TODO: Handle G_IMPLICIT_DEF, which is needed to have i8 -> i64 extends working +; on RV32. + +define i32 @add_i32(i32 %a, i32 %b) { +; RV32IM-LABEL: add_i32: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: add a0, a0, a1 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: add_i32: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: add a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = add i32 %a, %b + ret i32 %0 +} + +define i32 @sub_i32(i32 %a, i32 %b) { +; RV32IM-LABEL: sub_i32: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: sub a0, a0, a1 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: sub_i32: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: sub a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = sub i32 %a, %b + ret i32 %0 +} + +define i32 @shl_i32(i32 %a, i32 %b) { +; RV32IM-LABEL: shl_i32: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: sll a0, a0, a1 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: shl_i32: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: sll a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = shl i32 %a, %b + ret i32 %0 +} + +define i32 @ashr_i32(i32 %a, i32 %b) { +; RV32IM-LABEL: ashr_i32: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: sra a0, a0, a1 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: ashr_i32: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: sra a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = ashr i32 %a, %b + ret i32 %0 +} + +define i32 @lshr_i32(i32 %a, i32 %b) { +; RV32IM-LABEL: lshr_i32: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: srl a0, a0, a1 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: lshr_i32: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: srl a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = lshr i32 %a, %b + ret i32 %0 +} + +define i32 @and_i32(i32 %a, i32 %b) { +; RV32IM-LABEL: and_i32: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: and a0, a0, a1 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: and_i32: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: and a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = and i32 %a, %b + ret i32 %0 +} + +define i32 @or_i32(i32 %a, i32 %b) { +; RV32IM-LABEL: or_i32: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: or a0, a0, a1 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: or_i32: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: or a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = or i32 %a, %b + ret i32 %0 +} + +define i32 @xor_i32(i32 %a, i32 %b) { +; RV32IM-LABEL: xor_i32: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: xor a0, a0, a1 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: xor_i32: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: xor a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = xor i32 %a, %b + ret i32 %0 +} + +define i32 @mul_i32(i32 %a, i32 %b) { +; RV32IM-LABEL: mul_i32: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: mul a0, a0, a1 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: mul_i32: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: mul a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = mul i32 %a, %b + ret i32 %0 +} + +define i32 @sdiv_i32(i32 %a, i32 %b) { +; RV32IM-LABEL: sdiv_i32: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: div a0, a0, a1 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: sdiv_i32: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: div a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = sdiv i32 %a, %b + ret i32 %0 +} + +define i32 @srem_i32(i32 %a, i32 %b) { +; RV32IM-LABEL: srem_i32: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: rem a0, a0, a1 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: srem_i32: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: rem a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = srem i32 %a, %b + ret i32 %0 +} + +define i32 @udiv_i32(i32 %a, i32 %b) { +; RV32IM-LABEL: udiv_i32: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: divu a0, a0, a1 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: udiv_i32: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: divu a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = udiv i32 %a, %b + ret i32 %0 +} + +define i32 @urem_i32(i32 %a, i32 %b) { +; RV32IM-LABEL: urem_i32: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: remu a0, a0, a1 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: urem_i32: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: remu a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = urem i32 %a, %b + ret i32 %0 +} + +define i64 @add_i64(i64 %a, i64 %b) { +; RV32IM-LABEL: add_i64: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: add a0, a0, a2 +; RV32IM-NEXT: sltu a2, a0, a2 +; RV32IM-NEXT: add a1, a1, a3 +; RV32IM-NEXT: andi a2, a2, 1 +; RV32IM-NEXT: add a1, a1, a2 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: add_i64: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: add a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = add i64 %a, %b + ret i64 %0 +} + +define i64 @sub_i64(i64 %a, i64 %b) { +; RV32IM-LABEL: sub_i64: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: sub a4, a0, a2 +; RV32IM-NEXT: sltu a0, a0, a2 +; RV32IM-NEXT: sub a1, a1, a3 +; RV32IM-NEXT: andi a0, a0, 1 +; RV32IM-NEXT: sub a1, a1, a0 +; RV32IM-NEXT: mv a0, a4 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: sub_i64: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: sub a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = sub i64 %a, %b + ret i64 %0 +} + +; TODO: Handle G_SELECT, which is needed to have i64 shifts working on RV32. + +define i64 @and_i64(i64 %a, i64 %b) { +; RV32IM-LABEL: and_i64: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: and a0, a0, a2 +; RV32IM-NEXT: and a1, a1, a3 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: and_i64: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: and a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = and i64 %a, %b + ret i64 %0 +} + +define i64 @or_i64(i64 %a, i64 %b) { +; RV32IM-LABEL: or_i64: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: or a0, a0, a2 +; RV32IM-NEXT: or a1, a1, a3 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: or_i64: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: or a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = or i64 %a, %b + ret i64 %0 +} + +define i64 @xor_i64(i64 %a, i64 %b) { +; RV32IM-LABEL: xor_i64: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: xor a0, a0, a2 +; RV32IM-NEXT: xor a1, a1, a3 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: xor_i64: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: xor a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = xor i64 %a, %b + ret i64 %0 +} + +define i64 @mul_i64(i64 %a, i64 %b) { +; RV32IM-LABEL: mul_i64: +; RV32IM: # %bb.0: # %entry +; RV32IM-NEXT: mul a4, a0, a2 +; RV32IM-NEXT: mul a1, a1, a2 +; RV32IM-NEXT: mul a3, a0, a3 +; RV32IM-NEXT: mulhu a0, a0, a2 +; RV32IM-NEXT: add a1, a1, a3 +; RV32IM-NEXT: add a1, a1, a0 +; RV32IM-NEXT: mv a0, a4 +; RV32IM-NEXT: ret +; +; RV64IM-LABEL: mul_i64: +; RV64IM: # %bb.0: # %entry +; RV64IM-NEXT: mul a0, a0, a1 +; RV64IM-NEXT: ret +entry: + %0 = mul i64 %a, %b + ret i64 %0 +} + +; TODO: Handle G_SDIV, G_SREM, G_UDIV, G_UREM for i64 on RV32. Likely will be +; dispatched to a libcall? 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,412 @@ +# 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: 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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV32I-NEXT: $x10 = COPY [[ADD]] + ; RV32I-NEXT: 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: 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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV32I-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADD]], 24 + ; RV32I-NEXT: [[SRAI:%[0-9]+]]:gpr = SRAI [[SLLI]], 24 + ; RV32I-NEXT: $x10 = COPY [[SRAI]] + ; RV32I-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_ADD %0, %1 + %3:gprb(s32) = G_CONSTANT i32 24 + %4:gprb(s32) = G_SHL %2, %3(s32) + %5:gprb(s32) = G_ASHR %4, %3(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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV32I-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[ADD]], 255 + ; RV32I-NEXT: $x10 = COPY [[ANDI]] + ; RV32I-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_ADD %0, %1 + %3:gprb(s32) = G_CONSTANT i32 255 + %4:gprb(s32) = G_AND %2, %3 + $x10 = COPY %4(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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV32I-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADD]], 16 + ; RV32I-NEXT: [[SRAI:%[0-9]+]]:gpr = SRAI [[SLLI]], 16 + ; RV32I-NEXT: $x10 = COPY [[SRAI]] + ; RV32I-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_ADD %0, %1 + %3:gprb(s32) = G_CONSTANT i32 16 + %4:gprb(s32) = G_SHL %2, %3(s32) + %5:gprb(s32) = G_ASHR %4, %3(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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV32I-NEXT: [[LUI:%[0-9]+]]:gpr = LUI 16 + ; RV32I-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[LUI]], -1 + ; RV32I-NEXT: [[AND:%[0-9]+]]:gpr = AND [[ADD]], [[ADDI]] + ; RV32I-NEXT: $x10 = COPY [[AND]] + ; RV32I-NEXT: PseudoRET implicit $x10 + %0:gprb(s32) = COPY $x10 + %1:gprb(s32) = COPY $x11 + %2:gprb(s32) = G_ADD %0, %1 + %3:gprb(s32) = G_CONSTANT i32 65535 + %4:gprb(s32) = G_AND %2, %3 + $x10 = COPY %4(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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV32I-NEXT: $x10 = COPY [[ADD]] + ; RV32I-NEXT: 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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[SUB:%[0-9]+]]:gpr = SUB [[COPY]], [[COPY1]] + ; RV32I-NEXT: $x10 = COPY [[SUB]] + ; RV32I-NEXT: 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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[SLL:%[0-9]+]]:gpr = SLL [[COPY]], [[COPY1]] + ; RV32I-NEXT: $x10 = COPY [[SLL]] + ; RV32I-NEXT: 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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[SRA:%[0-9]+]]:gpr = SRA [[COPY]], [[COPY1]] + ; RV32I-NEXT: $x10 = COPY [[SRA]] + ; RV32I-NEXT: 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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[SRL:%[0-9]+]]:gpr = SRL [[COPY]], [[COPY1]] + ; RV32I-NEXT: $x10 = COPY [[SRL]] + ; RV32I-NEXT: 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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[AND:%[0-9]+]]:gpr = AND [[COPY]], [[COPY1]] + ; RV32I-NEXT: $x10 = COPY [[AND]] + ; RV32I-NEXT: 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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[OR:%[0-9]+]]:gpr = OR [[COPY]], [[COPY1]] + ; RV32I-NEXT: $x10 = COPY [[OR]] + ; RV32I-NEXT: 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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[XOR:%[0-9]+]]:gpr = XOR [[COPY]], [[COPY1]] + ; RV32I-NEXT: $x10 = COPY [[XOR]] + ; RV32I-NEXT: 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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12 + ; RV32I-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x13 + ; RV32I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY2]] + ; RV32I-NEXT: [[SLTU:%[0-9]+]]:gpr = SLTU [[ADD]], [[COPY2]] + ; RV32I-NEXT: [[ADD1:%[0-9]+]]:gpr = ADD [[COPY1]], [[COPY3]] + ; RV32I-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[SLTU]], 1 + ; RV32I-NEXT: [[ADD2:%[0-9]+]]:gpr = ADD [[ADD1]], [[ANDI]] + ; RV32I-NEXT: $x10 = COPY [[ADD]] + ; RV32I-NEXT: $x11 = COPY [[ADD2]] + ; RV32I-NEXT: 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 + %4:gprb(s32) = G_ADD %0, %2 + %5:gprb(s32) = G_ICMP intpred(ult), %4(s32), %2 + %6:gprb(s32) = G_ADD %1, %3 + %7:gprb(s32) = G_CONSTANT i32 1 + %8:gprb(s32) = G_AND %5, %7 + %9:gprb(s32) = G_ADD %6, %8 + $x10 = COPY %4(s32) + $x11 = COPY %9(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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12 + ; RV32I-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x13 + ; RV32I-NEXT: [[SUB:%[0-9]+]]:gpr = SUB [[COPY]], [[COPY2]] + ; RV32I-NEXT: [[SLTU:%[0-9]+]]:gpr = SLTU [[COPY]], [[COPY2]] + ; RV32I-NEXT: [[SUB1:%[0-9]+]]:gpr = SUB [[COPY1]], [[COPY3]] + ; RV32I-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[SLTU]], 1 + ; RV32I-NEXT: [[SUB2:%[0-9]+]]:gpr = SUB [[SUB1]], [[ANDI]] + ; RV32I-NEXT: $x10 = COPY [[SUB]] + ; RV32I-NEXT: $x11 = COPY [[SUB2]] + ; RV32I-NEXT: 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 + %4:gprb(s32) = G_SUB %0, %2 + %5:gprb(s32) = G_ICMP intpred(ult), %0(s32), %2 + %6:gprb(s32) = G_SUB %1, %3 + %7:gprb(s32) = G_CONSTANT i32 1 + %8:gprb(s32) = G_AND %5, %7 + %9:gprb(s32) = G_SUB %6, %8 + $x10 = COPY %4(s32) + $x11 = COPY %9(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,164 @@ +# 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 + +--- +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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[MUL:%[0-9]+]]:gpr = MUL [[COPY]], [[COPY1]] + ; RV32I-NEXT: $x10 = COPY [[MUL]] + ; RV32I-NEXT: 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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[DIV:%[0-9]+]]:gpr = DIV [[COPY]], [[COPY1]] + ; RV32I-NEXT: $x10 = COPY [[DIV]] + ; RV32I-NEXT: 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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[REM:%[0-9]+]]:gpr = REM [[COPY]], [[COPY1]] + ; RV32I-NEXT: $x10 = COPY [[REM]] + ; RV32I-NEXT: 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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[DIVU:%[0-9]+]]:gpr = DIVU [[COPY]], [[COPY1]] + ; RV32I-NEXT: $x10 = COPY [[DIVU]] + ; RV32I-NEXT: 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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[REMU:%[0-9]+]]:gpr = REMU [[COPY]], [[COPY1]] + ; RV32I-NEXT: $x10 = COPY [[REMU]] + ; RV32I-NEXT: 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-NEXT: {{ $}} + ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV32I-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12 + ; RV32I-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x13 + ; RV32I-NEXT: [[MUL:%[0-9]+]]:gpr = MUL [[COPY]], [[COPY2]] + ; RV32I-NEXT: [[MUL1:%[0-9]+]]:gpr = MUL [[COPY1]], [[COPY2]] + ; RV32I-NEXT: [[MUL2:%[0-9]+]]:gpr = MUL [[COPY]], [[COPY3]] + ; RV32I-NEXT: [[MULHU:%[0-9]+]]:gpr = MULHU [[COPY]], [[COPY2]] + ; RV32I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[MUL1]], [[MUL2]] + ; RV32I-NEXT: [[ADD1:%[0-9]+]]:gpr = ADD [[ADD]], [[MULHU]] + ; RV32I-NEXT: $x10 = COPY [[MUL]] + ; RV32I-NEXT: $x11 = COPY [[ADD1]] + ; RV32I-NEXT: 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 + %4:gprb(s32) = G_MUL %0, %2 + %5:gprb(s32) = G_MUL %1, %2 + %6:gprb(s32) = G_MUL %0, %3 + %7:gprb(s32) = G_UMULH %0, %2 + %8:gprb(s32) = G_ADD %5, %6 + %9:gprb(s32) = G_ADD %8, %7 + $x10 = COPY %4(s32) + $x11 = COPY %9(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,554 @@ +# 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: 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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV64I-NEXT: $x10 = COPY [[ADD]] + ; RV64I-NEXT: 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: 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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV64I-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADD]], 56 + ; RV64I-NEXT: [[SRAI:%[0-9]+]]:gpr = SRAI [[SLLI]], 56 + ; RV64I-NEXT: $x10 = COPY [[SRAI]] + ; RV64I-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_ADD %0, %1 + %3:gprb(s64) = G_CONSTANT i64 56 + %4:gprb(s64) = G_SHL %2, %3(s64) + %5:gprb(s64) = G_ASHR %4, %3(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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV64I-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[ADD]], 255 + ; RV64I-NEXT: $x10 = COPY [[ANDI]] + ; RV64I-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_ADD %0, %1 + %3:gprb(s64) = G_CONSTANT i64 255 + %4:gprb(s64) = G_AND %2, %3 + $x10 = COPY %4(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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV64I-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADD]], 48 + ; RV64I-NEXT: [[SRAI:%[0-9]+]]:gpr = SRAI [[SLLI]], 48 + ; RV64I-NEXT: $x10 = COPY [[SRAI]] + ; RV64I-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_ADD %0, %1 + %3:gprb(s64) = G_CONSTANT i64 48 + %4:gprb(s64) = G_SHL %2, %3(s64) + %5:gprb(s64) = G_ASHR %4, %3(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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV64I-NEXT: [[LUI:%[0-9]+]]:gpr = LUI 16 + ; RV64I-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[LUI]], -1 + ; RV64I-NEXT: [[AND:%[0-9]+]]:gpr = AND [[ADD]], [[ADDIW]] + ; RV64I-NEXT: $x10 = COPY [[AND]] + ; RV64I-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_ADD %0, %1 + %3:gprb(s64) = G_CONSTANT i64 65535 + %4:gprb(s64) = G_AND %2, %3 + $x10 = COPY %4(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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV64I-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADD]], 32 + ; RV64I-NEXT: [[SRAI:%[0-9]+]]:gpr = SRAI [[SLLI]], 32 + ; RV64I-NEXT: $x10 = COPY [[SRAI]] + ; RV64I-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_ADD %0, %1 + %3:gprb(s64) = G_CONSTANT i64 32 + %4:gprb(s64) = G_SHL %2, %3(s64) + %5:gprb(s64) = G_ASHR %4, %3(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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[SUB:%[0-9]+]]:gpr = SUB [[COPY]], [[COPY1]] + ; RV64I-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[SUB]], 32 + ; RV64I-NEXT: [[SRAI:%[0-9]+]]:gpr = SRAI [[SLLI]], 32 + ; RV64I-NEXT: $x10 = COPY [[SRAI]] + ; RV64I-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_SUB %0, %1 + %3:gprb(s64) = G_CONSTANT i64 32 + %4:gprb(s64) = G_SHL %2, %3(s64) + %5:gprb(s64) = G_ASHR %4, %3(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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[SLL:%[0-9]+]]:gpr = SLL [[COPY]], [[COPY1]] + ; RV64I-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[SLL]], 32 + ; RV64I-NEXT: [[SRLI:%[0-9]+]]:gpr = SRLI [[SLLI]], 32 + ; RV64I-NEXT: $x10 = COPY [[SRLI]] + ; RV64I-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_SHL %0, %1(s64) + %3:gprb(s64) = G_CONSTANT i64 4294967295 + %4:gprb(s64) = G_AND %2, %3 + $x10 = COPY %4(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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[SRA:%[0-9]+]]:gpr = SRA [[COPY]], [[COPY1]] + ; RV64I-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[SRA]], 32 + ; RV64I-NEXT: [[SRLI:%[0-9]+]]:gpr = SRLI [[SLLI]], 32 + ; RV64I-NEXT: $x10 = COPY [[SRLI]] + ; RV64I-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_ASHR %0, %1(s64) + %3:gprb(s64) = G_CONSTANT i64 4294967295 + %4:gprb(s64) = G_AND %2, %3 + $x10 = COPY %4(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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[SRL:%[0-9]+]]:gpr = SRL [[COPY]], [[COPY1]] + ; RV64I-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[SRL]], 32 + ; RV64I-NEXT: [[SRLI:%[0-9]+]]:gpr = SRLI [[SLLI]], 32 + ; RV64I-NEXT: $x10 = COPY [[SRLI]] + ; RV64I-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_LSHR %0, %1(s64) + %3:gprb(s64) = G_CONSTANT i64 4294967295 + %4:gprb(s64) = G_AND %2, %3 + $x10 = COPY %4(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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY1]] + ; RV64I-NEXT: $x10 = COPY [[ADD]] + ; RV64I-NEXT: 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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[SUB:%[0-9]+]]:gpr = SUB [[COPY]], [[COPY1]] + ; RV64I-NEXT: $x10 = COPY [[SUB]] + ; RV64I-NEXT: 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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[SLL:%[0-9]+]]:gpr = SLL [[COPY]], [[COPY1]] + ; RV64I-NEXT: $x10 = COPY [[SLL]] + ; RV64I-NEXT: 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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[SRA:%[0-9]+]]:gpr = SRA [[COPY]], [[COPY1]] + ; RV64I-NEXT: $x10 = COPY [[SRA]] + ; RV64I-NEXT: 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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[SRL:%[0-9]+]]:gpr = SRL [[COPY]], [[COPY1]] + ; RV64I-NEXT: $x10 = COPY [[SRL]] + ; RV64I-NEXT: 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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[AND:%[0-9]+]]:gpr = AND [[COPY]], [[COPY1]] + ; RV64I-NEXT: $x10 = COPY [[AND]] + ; RV64I-NEXT: 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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[OR:%[0-9]+]]:gpr = OR [[COPY]], [[COPY1]] + ; RV64I-NEXT: $x10 = COPY [[OR]] + ; RV64I-NEXT: 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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[XOR:%[0-9]+]]:gpr = XOR [[COPY]], [[COPY1]] + ; RV64I-NEXT: $x10 = COPY [[XOR]] + ; RV64I-NEXT: 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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12 + ; RV64I-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x13 + ; RV64I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[COPY]], [[COPY2]] + ; RV64I-NEXT: [[SLTU:%[0-9]+]]:gpr = SLTU [[ADD]], [[COPY2]] + ; RV64I-NEXT: [[ADD1:%[0-9]+]]:gpr = ADD [[COPY1]], [[COPY3]] + ; RV64I-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[SLTU]], 1 + ; RV64I-NEXT: [[ADD2:%[0-9]+]]:gpr = ADD [[ADD1]], [[ANDI]] + ; RV64I-NEXT: $x10 = COPY [[ADD]] + ; RV64I-NEXT: $x11 = COPY [[ADD2]] + ; RV64I-NEXT: 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 + %4:gprb(s64) = G_ADD %0, %2 + %5:gprb(s64) = G_ICMP intpred(ult), %4(s64), %2 + %6:gprb(s64) = G_ADD %1, %3 + %7:gprb(s64) = G_CONSTANT i64 1 + %8:gprb(s64) = G_AND %5, %7 + %9:gprb(s64) = G_ADD %6, %8 + $x10 = COPY %4(s64) + $x11 = COPY %9(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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12 + ; RV64I-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x13 + ; RV64I-NEXT: [[SUB:%[0-9]+]]:gpr = SUB [[COPY]], [[COPY2]] + ; RV64I-NEXT: [[SLTU:%[0-9]+]]:gpr = SLTU [[COPY]], [[COPY2]] + ; RV64I-NEXT: [[SUB1:%[0-9]+]]:gpr = SUB [[COPY1]], [[COPY3]] + ; RV64I-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[SLTU]], 1 + ; RV64I-NEXT: [[SUB2:%[0-9]+]]:gpr = SUB [[SUB1]], [[ANDI]] + ; RV64I-NEXT: $x10 = COPY [[SUB]] + ; RV64I-NEXT: $x11 = COPY [[SUB2]] + ; RV64I-NEXT: 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 + %4:gprb(s64) = G_SUB %0, %2 + %5:gprb(s64) = G_ICMP intpred(ult), %0(s64), %2 + %6:gprb(s64) = G_SUB %1, %3 + %7:gprb(s64) = G_CONSTANT i64 1 + %8:gprb(s64) = G_AND %5, %7 + %9:gprb(s64) = G_SUB %6, %8 + $x10 = COPY %4(s64) + $x11 = COPY %9(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,307 @@ +# 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 + +--- +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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[MUL:%[0-9]+]]:gpr = MUL [[COPY]], [[COPY1]] + ; RV64I-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[MUL]], 32 + ; RV64I-NEXT: [[SRAI:%[0-9]+]]:gpr = SRAI [[SLLI]], 32 + ; RV64I-NEXT: $x10 = COPY [[SRAI]] + ; RV64I-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_MUL %0, %1 + %3:gprb(s64) = G_CONSTANT i64 32 + %4:gprb(s64) = G_SHL %2, %3(s64) + %5:gprb(s64) = G_ASHR %4, %3(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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[DIV:%[0-9]+]]:gpr = DIV [[COPY]], [[COPY1]] + ; RV64I-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[DIV]], 32 + ; RV64I-NEXT: [[SRAI:%[0-9]+]]:gpr = SRAI [[SLLI]], 32 + ; RV64I-NEXT: $x10 = COPY [[SRAI]] + ; RV64I-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_SDIV %0, %1 + %3:gprb(s64) = G_CONSTANT i64 32 + %4:gprb(s64) = G_SHL %2, %3(s64) + %5:gprb(s64) = G_ASHR %4, %3(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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[REM:%[0-9]+]]:gpr = REM [[COPY]], [[COPY1]] + ; RV64I-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[REM]], 32 + ; RV64I-NEXT: [[SRAI:%[0-9]+]]:gpr = SRAI [[SLLI]], 32 + ; RV64I-NEXT: $x10 = COPY [[SRAI]] + ; RV64I-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_SREM %0, %1 + %3:gprb(s64) = G_CONSTANT i64 32 + %4:gprb(s64) = G_SHL %2, %3(s64) + %5:gprb(s64) = G_ASHR %4, %3(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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[DIVU:%[0-9]+]]:gpr = DIVU [[COPY]], [[COPY1]] + ; RV64I-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[DIVU]], 32 + ; RV64I-NEXT: [[SRLI:%[0-9]+]]:gpr = SRLI [[SLLI]], 32 + ; RV64I-NEXT: $x10 = COPY [[SRLI]] + ; RV64I-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_UDIV %0, %1 + %3:gprb(s64) = G_CONSTANT i64 4294967295 + %4:gprb(s64) = G_AND %2, %3 + $x10 = COPY %4(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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[REMU:%[0-9]+]]:gpr = REMU [[COPY]], [[COPY1]] + ; RV64I-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[REMU]], 32 + ; RV64I-NEXT: [[SRLI:%[0-9]+]]:gpr = SRLI [[SLLI]], 32 + ; RV64I-NEXT: $x10 = COPY [[SRLI]] + ; RV64I-NEXT: PseudoRET implicit $x10 + %0:gprb(s64) = COPY $x10 + %1:gprb(s64) = COPY $x11 + %2:gprb(s64) = G_UREM %0, %1 + %3:gprb(s64) = G_CONSTANT i64 4294967295 + %4:gprb(s64) = G_AND %2, %3 + $x10 = COPY %4(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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[MUL:%[0-9]+]]:gpr = MUL [[COPY]], [[COPY1]] + ; RV64I-NEXT: $x10 = COPY [[MUL]] + ; RV64I-NEXT: 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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[DIV:%[0-9]+]]:gpr = DIV [[COPY]], [[COPY1]] + ; RV64I-NEXT: $x10 = COPY [[DIV]] + ; RV64I-NEXT: 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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[REM:%[0-9]+]]:gpr = REM [[COPY]], [[COPY1]] + ; RV64I-NEXT: $x10 = COPY [[REM]] + ; RV64I-NEXT: 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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[DIVU:%[0-9]+]]:gpr = DIVU [[COPY]], [[COPY1]] + ; RV64I-NEXT: $x10 = COPY [[DIVU]] + ; RV64I-NEXT: 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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[REMU:%[0-9]+]]:gpr = REMU [[COPY]], [[COPY1]] + ; RV64I-NEXT: $x10 = COPY [[REMU]] + ; RV64I-NEXT: 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-NEXT: {{ $}} + ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 + ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; RV64I-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12 + ; RV64I-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x13 + ; RV64I-NEXT: [[MUL:%[0-9]+]]:gpr = MUL [[COPY]], [[COPY2]] + ; RV64I-NEXT: [[MUL1:%[0-9]+]]:gpr = MUL [[COPY1]], [[COPY2]] + ; RV64I-NEXT: [[MUL2:%[0-9]+]]:gpr = MUL [[COPY]], [[COPY3]] + ; RV64I-NEXT: [[MULHU:%[0-9]+]]:gpr = MULHU [[COPY]], [[COPY2]] + ; RV64I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[MUL1]], [[MUL2]] + ; RV64I-NEXT: [[ADD1:%[0-9]+]]:gpr = ADD [[ADD]], [[MULHU]] + ; RV64I-NEXT: $x10 = COPY [[MUL]] + ; RV64I-NEXT: $x11 = COPY [[ADD1]] + ; RV64I-NEXT: 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 + %4:gprb(s64) = G_MUL %0, %2 + %5:gprb(s64) = G_MUL %1, %2 + %6:gprb(s64) = G_MUL %0, %3 + %7:gprb(s64) = G_UMULH %0, %2 + %8:gprb(s64) = G_ADD %5, %6 + %9:gprb(s64) = G_ADD %8, %7 + $x10 = COPY %4(s64) + $x11 = COPY %9(s64) + PseudoRET implicit $x10, implicit $x11 + +... 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 + +...