25#include "llvm/IR/IntrinsicsRISCV.h"
28#define DEBUG_TYPE "riscv-isel"
33#define GET_GLOBALISEL_PREDICATE_BITSET
34#include "RISCVGenGlobalISel.inc"
35#undef GET_GLOBALISEL_PREDICATE_BITSET
60 static constexpr unsigned MaxRecursionDepth = 6;
63 const unsigned Depth = 0)
const;
89 bool IsExternWeak =
false)
const;
97 unsigned &CurOp,
bool IsMasked,
98 bool IsStridedOrIndexed,
99 LLT *IndexVT =
nullptr)
const;
105 unsigned ShiftWidth)
const;
106 ComplexRendererFns selectShiftMaskXLen(
MachineOperand &Root)
const {
107 return selectShiftMask(Root, STI.
getXLen());
109 ComplexRendererFns selectShiftMask32(
MachineOperand &Root)
const {
110 return selectShiftMask(Root, 32);
114 ComplexRendererFns selectSExtBits(
MachineOperand &Root,
unsigned Bits)
const;
115 template <
unsigned Bits>
117 return selectSExtBits(Root, Bits);
120 ComplexRendererFns selectZExtBits(
MachineOperand &Root,
unsigned Bits)
const;
121 template <
unsigned Bits>
123 return selectZExtBits(Root, Bits);
126 ComplexRendererFns selectSHXADDOp(
MachineOperand &Root,
unsigned ShAmt)
const;
127 template <
unsigned ShAmt>
129 return selectSHXADDOp(Root, ShAmt);
133 unsigned ShAmt)
const;
134 template <
unsigned ShAmt>
135 ComplexRendererFns selectSHXADD_UWOp(
MachineOperand &Root)
const {
136 return selectSHXADD_UWOp(Root, ShAmt);
176#define GET_GLOBALISEL_PREDICATES_DECL
177#include "RISCVGenGlobalISel.inc"
178#undef GET_GLOBALISEL_PREDICATES_DECL
180#define GET_GLOBALISEL_TEMPORARIES_DECL
181#include "RISCVGenGlobalISel.inc"
182#undef GET_GLOBALISEL_TEMPORARIES_DECL
187#define GET_GLOBALISEL_IMPL
188#include "RISCVGenGlobalISel.inc"
189#undef GET_GLOBALISEL_IMPL
191RISCVInstructionSelector::RISCVInstructionSelector(
194 : STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()), RBI(RBI),
198#include
"RISCVGenGlobalISel.inc"
201#include
"RISCVGenGlobalISel.inc"
207bool RISCVInstructionSelector::hasAllNBitUsers(
const MachineInstr &
MI,
209 const unsigned Depth)
const {
211 assert((
MI.getOpcode() == TargetOpcode::G_ADD ||
212 MI.getOpcode() == TargetOpcode::G_SUB ||
213 MI.getOpcode() == TargetOpcode::G_MUL ||
214 MI.getOpcode() == TargetOpcode::G_SHL ||
215 MI.getOpcode() == TargetOpcode::G_LSHR ||
216 MI.getOpcode() == TargetOpcode::G_AND ||
217 MI.getOpcode() == TargetOpcode::G_OR ||
218 MI.getOpcode() == TargetOpcode::G_XOR ||
219 MI.getOpcode() == TargetOpcode::G_SEXT_INREG ||
Depth != 0) &&
220 "Unexpected opcode");
222 if (
Depth >= RISCVInstructionSelector::MaxRecursionDepth)
225 auto DestReg =
MI.getOperand(0).getReg();
226 for (
auto &UserOp :
MRI->use_nodbg_operands(DestReg)) {
227 assert(UserOp.getParent() &&
"UserOp must have a parent");
228 const MachineInstr &UserMI = *UserOp.getParent();
237 case RISCV::FCVT_D_W:
238 case RISCV::FCVT_S_W:
281InstructionSelector::ComplexRendererFns
282RISCVInstructionSelector::selectShiftMask(MachineOperand &Root,
283 unsigned ShiftWidth)
const {
287 using namespace llvm::MIPatternMatch;
293 ShAmtReg = ZExtSrcReg;
312 APInt ShMask(AndMask.
getBitWidth(), ShiftWidth - 1);
313 if (ShMask.isSubsetOf(AndMask)) {
314 ShAmtReg = AndSrcReg;
318 KnownBits Known = VT->getKnownBits(AndSrcReg);
319 if (ShMask.isSubsetOf(AndMask | Known.
Zero))
320 ShAmtReg = AndSrcReg;
327 if (Imm != 0 &&
Imm.urem(ShiftWidth) == 0)
332 if (Imm != 0 &&
Imm.urem(ShiftWidth) == 0) {
335 ShAmtReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
336 unsigned NegOpc = Subtarget->
is64Bit() ? RISCV::SUBW : RISCV::SUB;
337 return {{[=](MachineInstrBuilder &MIB) {
338 MachineIRBuilder(*MIB.getInstr())
339 .buildInstr(NegOpc, {ShAmtReg}, {
Register(RISCV::X0),
Reg});
340 MIB.addReg(ShAmtReg);
343 if (
Imm.urem(ShiftWidth) == ShiftWidth - 1) {
346 ShAmtReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
347 return {{[=](MachineInstrBuilder &MIB) {
348 MachineIRBuilder(*MIB.getInstr())
349 .buildInstr(RISCV::XORI, {ShAmtReg}, {
Reg})
351 MIB.addReg(ShAmtReg);
356 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(ShAmtReg); }}};
359InstructionSelector::ComplexRendererFns
360RISCVInstructionSelector::selectSExtBits(MachineOperand &Root,
361 unsigned Bits)
const {
365 MachineInstr *RootDef =
MRI->getVRegDef(RootReg);
367 if (RootDef->
getOpcode() == TargetOpcode::G_SEXT_INREG &&
370 {[=](MachineInstrBuilder &MIB) { MIB.add(RootDef->
getOperand(1)); }}};
373 unsigned Size =
MRI->getType(RootReg).getScalarSizeInBits();
374 if ((
Size - VT->computeNumSignBits(RootReg)) < Bits)
375 return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
380InstructionSelector::ComplexRendererFns
381RISCVInstructionSelector::selectZExtBits(MachineOperand &Root,
382 unsigned Bits)
const {
390 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}};
394 MRI->getType(RegX).getScalarSizeInBits() == Bits)
395 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}};
397 unsigned Size =
MRI->getType(RootReg).getScalarSizeInBits();
399 return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
404InstructionSelector::ComplexRendererFns
405RISCVInstructionSelector::selectSHXADDOp(MachineOperand &Root,
406 unsigned ShAmt)
const {
407 using namespace llvm::MIPatternMatch;
413 const unsigned XLen = STI.
getXLen();
432 if (
Mask.isShiftedMask()) {
433 unsigned Leading = XLen -
Mask.getActiveBits();
434 unsigned Trailing =
Mask.countr_zero();
437 if (*LeftShift && Leading == 0 && C2.
ult(Trailing) && Trailing == ShAmt) {
438 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
439 return {{[=](MachineInstrBuilder &MIB) {
440 MachineIRBuilder(*MIB.getInstr())
441 .buildInstr(RISCV::SRLI, {DstReg}, {RegY})
449 if (!*LeftShift && Leading == C2 && Trailing == ShAmt) {
450 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
451 return {{[=](MachineInstrBuilder &MIB) {
452 MachineIRBuilder(*MIB.getInstr())
453 .buildInstr(RISCV::SRLI, {DstReg}, {RegY})
454 .addImm(Leading + Trailing);
475 unsigned Leading = XLen -
Mask.getActiveBits();
476 unsigned Trailing =
Mask.countr_zero();
489 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
490 return {{[=](MachineInstrBuilder &MIB) {
491 MachineIRBuilder(*MIB.getInstr())
492 .buildInstr(RISCV::SRLIW, {DstReg}, {RegY})
502InstructionSelector::ComplexRendererFns
503RISCVInstructionSelector::selectSHXADD_UWOp(MachineOperand &Root,
504 unsigned ShAmt)
const {
505 using namespace llvm::MIPatternMatch;
522 if (
Mask.isShiftedMask()) {
523 unsigned Leading =
Mask.countl_zero();
524 unsigned Trailing =
Mask.countr_zero();
525 if (Leading == 32 - ShAmt && C2 == Trailing && Trailing > ShAmt) {
526 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
527 return {{[=](MachineInstrBuilder &MIB) {
528 MachineIRBuilder(*MIB.getInstr())
529 .buildInstr(RISCV::SLLI, {DstReg}, {RegX})
540InstructionSelector::ComplexRendererFns
541RISCVInstructionSelector::renderVLOp(MachineOperand &Root)
const {
542 assert(Root.
isReg() &&
"Expected operand to be a Register");
543 MachineInstr *RootDef =
MRI->getVRegDef(Root.
getReg());
545 if (RootDef->
getOpcode() == TargetOpcode::G_CONSTANT) {
547 if (
C->getValue().isAllOnes())
551 return {{[=](MachineInstrBuilder &MIB) {
556 uint64_t ZExtC =
C->getZExtValue();
557 return {{[=](MachineInstrBuilder &MIB) { MIB.addImm(ZExtC); }}};
560 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.
getReg()); }}};
563InstructionSelector::ComplexRendererFns
564RISCVInstructionSelector::selectAddrRegImm(MachineOperand &Root)
const {
568 MachineInstr *RootDef =
MRI->getVRegDef(Root.
getReg());
569 if (RootDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX) {
571 [=](MachineInstrBuilder &MIB) { MIB.add(RootDef->
getOperand(1)); },
572 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
576 if (isBaseWithConstantOffset(Root, *
MRI)) {
579 MachineInstr *LHSDef =
MRI->getVRegDef(
LHS.getReg());
580 MachineInstr *RHSDef =
MRI->getVRegDef(
RHS.getReg());
584 if (LHSDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX)
586 [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->
getOperand(1)); },
587 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
590 return {{[=](MachineInstrBuilder &MIB) { MIB.add(
LHS); },
591 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }}};
597 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.
getReg()); },
598 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
607 case CmpInst::Predicate::ICMP_EQ:
609 case CmpInst::Predicate::ICMP_NE:
611 case CmpInst::Predicate::ICMP_ULT:
613 case CmpInst::Predicate::ICMP_SLT:
615 case CmpInst::Predicate::ICMP_UGE:
617 case CmpInst::Predicate::ICMP_SGE:
683 CC = getRISCVCCFromICmp(Pred);
690 const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
695 return IsStore ? RISCV::SB_RL : RISCV::LB_AQ;
697 return IsStore ? RISCV::SH_RL : RISCV::LH_AQ;
699 return IsStore ? RISCV::SW_RL : RISCV::LW_AQ;
701 return IsStore ? RISCV::SD_RL : RISCV::LD_AQ;
709 const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
713 return IsStore ? RISCV::SB : RISCV::LBU;
715 return IsStore ? RISCV::SH : RISCV::LH;
717 return IsStore ? RISCV::SW : RISCV::LW;
719 return IsStore ? RISCV::SD : RISCV::LD;
725void RISCVInstructionSelector::addVectorLoadStoreOperands(
726 MachineInstr &
I, SmallVectorImpl<Register> &SrcOps,
unsigned &CurOp,
727 bool IsMasked,
bool IsStridedOrIndexed, LLT *IndexVT)
const {
729 auto PtrReg =
I.getOperand(CurOp++).getReg();
733 if (IsStridedOrIndexed) {
734 auto StrideReg =
I.getOperand(CurOp++).getReg();
737 *IndexVT =
MRI->getType(StrideReg);
742 auto MaskReg =
I.getOperand(CurOp++).getReg();
747bool RISCVInstructionSelector::selectIntrinsicWithSideEffects(
748 MachineInstr &
I)
const {
755 case Intrinsic::riscv_vlm:
756 case Intrinsic::riscv_vle:
757 case Intrinsic::riscv_vle_mask:
758 case Intrinsic::riscv_vlse:
759 case Intrinsic::riscv_vlse_mask: {
760 bool IsMasked = IntrinID == Intrinsic::riscv_vle_mask ||
761 IntrinID == Intrinsic::riscv_vlse_mask;
762 bool IsStrided = IntrinID == Intrinsic::riscv_vlse ||
763 IntrinID == Intrinsic::riscv_vlse_mask;
764 LLT VT =
MRI->getType(
I.getOperand(0).getReg());
768 const Register DstReg =
I.getOperand(0).getReg();
771 bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
776 if (HasPassthruOperand) {
777 auto PassthruReg =
I.getOperand(CurOp++).getReg();
783 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked, IsStrided);
786 const RISCV::VLEPseudo *
P =
787 RISCV::getVLEPseudo(IsMasked, IsStrided,
false, Log2SEW,
788 static_cast<unsigned>(LMUL));
790 MachineInstrBuilder PseudoMI =
791 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(
P->Pseudo), DstReg);
796 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
797 for (
auto &RenderFn : *VLOpFn)
806 Policy =
I.getOperand(CurOp++).getImm();
816 case Intrinsic::riscv_vloxei:
817 case Intrinsic::riscv_vloxei_mask:
818 case Intrinsic::riscv_vluxei:
819 case Intrinsic::riscv_vluxei_mask: {
820 bool IsMasked = IntrinID == Intrinsic::riscv_vloxei_mask ||
821 IntrinID == Intrinsic::riscv_vluxei_mask;
822 bool IsOrdered = IntrinID == Intrinsic::riscv_vloxei ||
823 IntrinID == Intrinsic::riscv_vloxei_mask;
824 LLT VT =
MRI->getType(
I.getOperand(0).getReg());
828 const Register DstReg =
I.getOperand(0).getReg();
831 bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
836 if (HasPassthruOperand) {
837 auto PassthruReg =
I.getOperand(CurOp++).getReg();
844 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked,
true, &IndexVT);
850 if (IndexLog2EEW == 6 && !Subtarget->
is64Bit()) {
852 "values when XLEN=32");
854 const RISCV::VLX_VSXPseudo *
P = RISCV::getVLXPseudo(
855 IsMasked, IsOrdered, IndexLog2EEW,
static_cast<unsigned>(LMUL),
856 static_cast<unsigned>(IndexLMUL));
858 MachineInstrBuilder PseudoMI =
859 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(
P->Pseudo), DstReg);
864 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
865 for (
auto &RenderFn : *VLOpFn)
874 Policy =
I.getOperand(CurOp++).getImm();
884 case Intrinsic::riscv_vsm:
885 case Intrinsic::riscv_vse:
886 case Intrinsic::riscv_vse_mask:
887 case Intrinsic::riscv_vsse:
888 case Intrinsic::riscv_vsse_mask: {
889 bool IsMasked = IntrinID == Intrinsic::riscv_vse_mask ||
890 IntrinID == Intrinsic::riscv_vsse_mask;
891 bool IsStrided = IntrinID == Intrinsic::riscv_vsse ||
892 IntrinID == Intrinsic::riscv_vsse_mask;
893 LLT VT =
MRI->getType(
I.getOperand(1).getReg());
901 auto PassthruReg =
I.getOperand(CurOp++).getReg();
904 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked, IsStrided);
907 const RISCV::VSEPseudo *
P = RISCV::getVSEPseudo(
908 IsMasked, IsStrided, Log2SEW,
static_cast<unsigned>(LMUL));
910 MachineInstrBuilder PseudoMI =
916 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
917 for (
auto &RenderFn : *VLOpFn)
930 case Intrinsic::riscv_vsoxei:
931 case Intrinsic::riscv_vsoxei_mask:
932 case Intrinsic::riscv_vsuxei:
933 case Intrinsic::riscv_vsuxei_mask: {
934 bool IsMasked = IntrinID == Intrinsic::riscv_vsoxei_mask ||
935 IntrinID == Intrinsic::riscv_vsuxei_mask;
936 bool IsOrdered = IntrinID == Intrinsic::riscv_vsoxei ||
937 IntrinID == Intrinsic::riscv_vsoxei_mask;
938 LLT VT =
MRI->getType(
I.getOperand(1).getReg());
946 auto PassthruReg =
I.getOperand(CurOp++).getReg();
950 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked,
true, &IndexVT);
956 if (IndexLog2EEW == 6 && !Subtarget->
is64Bit()) {
958 "values when XLEN=32");
960 const RISCV::VLX_VSXPseudo *
P = RISCV::getVSXPseudo(
961 IsMasked, IsOrdered, IndexLog2EEW,
static_cast<unsigned>(LMUL),
962 static_cast<unsigned>(IndexLMUL));
964 MachineInstrBuilder PseudoMI =
970 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
971 for (
auto &RenderFn : *VLOpFn)
987bool RISCVInstructionSelector::selectIntrinsic(MachineInstr &
I)
const {
994 case Intrinsic::riscv_vsetvli:
995 case Intrinsic::riscv_vsetvlimax: {
997 bool VLMax = IntrinID == Intrinsic::riscv_vsetvlimax;
999 unsigned Offset = VLMax ? 2 : 3;
1007 Register DstReg =
I.getOperand(0).getReg();
1010 unsigned Opcode = RISCV::PseudoVSETVLI;
1014 Register AVLReg =
I.getOperand(2).getReg();
1016 uint64_t AVL = AVLConst->Value.getZExtValue();
1023 MachineInstr *AVLDef =
MRI->getVRegDef(AVLReg);
1024 if (AVLDef && AVLDef->
getOpcode() == TargetOpcode::G_CONSTANT) {
1026 if (
C->getValue().isAllOnes())
1033 Opcode = RISCV::PseudoVSETVLIX0;
1035 Register AVLReg =
I.getOperand(2).getReg();
1040 uint64_t AVL = AVLConst->Value.getZExtValue();
1042 MachineInstr *PseudoMI =
1044 TII.get(RISCV::PseudoVSETIVLI), DstReg)
1047 I.eraseFromParent();
1054 MachineInstr *PseudoMI =
1055 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode), DstReg)
1058 I.eraseFromParent();
1065bool RISCVInstructionSelector::selectExtractSubvector(MachineInstr &
MI)
const {
1066 assert(
MI.getOpcode() == TargetOpcode::G_EXTRACT_SUBVECTOR);
1071 LLT DstTy =
MRI->getType(DstReg);
1072 LLT SrcTy =
MRI->getType(SrcReg);
1074 unsigned Idx =
static_cast<unsigned>(
MI.getOperand(2).
getImm());
1080 std::tie(SubRegIdx, Idx) =
1082 SrcMVT, DstMVT, Idx, &
TRI);
1088 const TargetRegisterClass *DstRC =
TRI.getRegClass(DstRegClassID);
1093 const TargetRegisterClass *SrcRC =
TRI.getRegClass(SrcRegClassID);
1097 BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1099 .
addReg(SrcReg, {}, SubRegIdx);
1101 MI.eraseFromParent();
1105bool RISCVInstructionSelector::select(MachineInstr &
MI) {
1107 const unsigned Opc =
MI.getOpcode();
1109 if (!
MI.isPreISelOpcode() ||
Opc == TargetOpcode::G_PHI) {
1110 if (
Opc == TargetOpcode::PHI ||
Opc == TargetOpcode::G_PHI) {
1111 const Register DefReg =
MI.getOperand(0).getReg();
1112 const LLT DefTy =
MRI->getType(DefReg);
1115 MRI->getRegClassOrRegBank(DefReg);
1117 const TargetRegisterClass *DefRC =
1126 DefRC = getRegClassForTypeOnBank(DefTy, RB);
1133 MI.setDesc(
TII.get(TargetOpcode::PHI));
1144 if (selectImpl(
MI, *CoverageInfo))
1148 case TargetOpcode::G_ANYEXT:
1149 case TargetOpcode::G_PTRTOINT:
1150 case TargetOpcode::G_INTTOPTR:
1151 case TargetOpcode::G_TRUNC:
1152 case TargetOpcode::G_FREEZE:
1154 case TargetOpcode::G_CONSTANT: {
1156 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
1158 if (!materializeImm(DstReg, Imm,
MI))
1161 MI.eraseFromParent();
1164 case TargetOpcode::G_ZEXT:
1165 case TargetOpcode::G_SEXT: {
1166 bool IsSigned =
Opc != TargetOpcode::G_ZEXT;
1169 LLT SrcTy =
MRI->getType(SrcReg);
1176 RISCV::GPRBRegBankID &&
1177 "Unexpected ext regbank");
1180 if (IsSigned && SrcSize == 32) {
1181 MI.setDesc(
TII.get(RISCV::ADDIW));
1188 if (!IsSigned && SrcSize == 32 && STI.hasStdExtZba()) {
1189 MI.setDesc(
TII.get(RISCV::ADD_UW));
1196 if (SrcSize == 16 &&
1197 (STI.hasStdExtZbb() || (!IsSigned && STI.hasStdExtZbkb()))) {
1198 MI.setDesc(
TII.get(IsSigned ? RISCV::SEXT_H
1199 : STI.isRV64() ? RISCV::ZEXT_H_RV64
1200 : RISCV::ZEXT_H_RV32));
1206 Register ShiftLeftReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1207 MachineInstr *ShiftLeft =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1208 TII.get(RISCV::SLLI), ShiftLeftReg)
1212 MachineInstr *ShiftRight =
1214 TII.get(IsSigned ? RISCV::SRAI : RISCV::SRLI), DstReg)
1218 MI.eraseFromParent();
1221 case TargetOpcode::G_FCONSTANT: {
1224 const APFloat &FPimm =
MI.getOperand(1).getFPImm()->getValueAPF();
1225 unsigned Size =
MRI->getType(DstReg).getSizeInBits();
1231 GPRReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1233 if (!materializeImm(GPRReg,
Imm.getSExtValue(),
MI))
1237 unsigned Opcode =
Size == 64 ? RISCV::FMV_D_X
1238 :
Size == 32 ? RISCV::FMV_W_X
1240 MachineInstr *FMV =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1241 TII.get(Opcode), DstReg)
1247 "Unexpected size or subtarget");
1251 MachineInstr *FCVT =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1252 TII.get(RISCV::FCVT_D_W), DstReg)
1257 MI.eraseFromParent();
1262 Register GPRRegHigh =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1263 Register GPRRegLow =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1265 if (!materializeImm(GPRRegHigh,
Imm.extractBits(32, 32).getSExtValue(),
1268 if (!materializeImm(GPRRegLow,
Imm.trunc(32).getSExtValue(),
MI))
1270 MachineInstr *PairF64 =
1272 TII.get(RISCV::BuildPairF64Pseudo), DstReg)
1278 MI.eraseFromParent();
1281 case TargetOpcode::G_GLOBAL_VALUE: {
1282 auto *GV =
MI.getOperand(1).getGlobal();
1283 if (GV->isThreadLocal()) {
1288 return selectAddr(
MI, GV->isDSOLocal(), GV->hasExternalWeakLinkage());
1290 case TargetOpcode::G_JUMP_TABLE:
1291 case TargetOpcode::G_CONSTANT_POOL:
1292 return selectAddr(
MI);
1293 case TargetOpcode::G_BRCOND: {
1298 MachineInstr *Bcc =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1302 .
addMBB(
MI.getOperand(1).getMBB());
1303 MI.eraseFromParent();
1307 case TargetOpcode::G_BRINDIRECT:
1308 MI.setDesc(
TII.get(RISCV::PseudoBRIND));
1312 case TargetOpcode::G_SELECT:
1313 return selectSelect(
MI);
1314 case TargetOpcode::G_FCMP:
1315 return selectFPCompare(
MI);
1316 case TargetOpcode::G_FENCE: {
1321 emitFence(FenceOrdering, FenceSSID,
MI);
1322 MI.eraseFromParent();
1325 case TargetOpcode::G_IMPLICIT_DEF:
1326 return selectImplicitDef(
MI);
1327 case TargetOpcode::G_UNMERGE_VALUES:
1329 case TargetOpcode::G_LOAD:
1330 case TargetOpcode::G_STORE: {
1334 LLT PtrTy =
MRI->getType(PtrReg);
1337 if (RB.
getID() != RISCV::GPRBRegBankID)
1344 "Load/Store pointer operand isn't a GPR");
1345 assert(PtrTy.
isPointer() &&
"Load/Store pointer operand isn't a pointer");
1362 if (NewOpc ==
MI.getOpcode())
1366 auto AddrModeFns = selectAddrRegImm(
MI.getOperand(1));
1371 MachineInstrBuilder NewInst =
1379 for (
auto &Fn : *AddrModeFns)
1381 MI.eraseFromParent();
1386 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
1387 return selectIntrinsicWithSideEffects(
MI);
1388 case TargetOpcode::G_INTRINSIC:
1389 return selectIntrinsic(
MI);
1390 case TargetOpcode::G_EXTRACT_SUBVECTOR:
1391 return selectExtractSubvector(
MI);
1397bool RISCVInstructionSelector::selectUnmergeValues(MachineInstr &
MI)
const {
1398 assert(
MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
1400 if (!Subtarget->hasStdExtZfa())
1404 if (
MI.getNumOperands() != 3)
1409 if (!isRegInFprb(Src) || !isRegInGprb(
Lo) || !isRegInGprb(
Hi))
1412 MachineInstr *ExtractLo =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1413 TII.get(RISCV::FMV_X_W_FPR64),
Lo)
1417 MachineInstr *ExtractHi =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1418 TII.get(RISCV::FMVH_X_D),
Hi)
1422 MI.eraseFromParent();
1426bool RISCVInstructionSelector::replacePtrWithInt(MachineOperand &
Op) {
1428 assert(
MRI->getType(PtrReg).isPointer() &&
"Operand is not a pointer!");
1431 MachineInstr &ParentMI = *
Op.getParent();
1432 Register IntReg =
MRI->createGenericVirtualRegister(sXLen);
1433 MRI->setRegBank(IntReg, RBI.
getRegBank(RISCV::GPRBRegBankID));
1434 MachineInstr *PtrToInt =
1436 TII.get(TargetOpcode::G_PTRTOINT), IntReg)
1439 return select(*PtrToInt);
1442void RISCVInstructionSelector::preISelLower(MachineInstr &
MI) {
1443 switch (
MI.getOpcode()) {
1444 case TargetOpcode::G_PTR_ADD: {
1448 replacePtrWithInt(
MI.getOperand(1));
1449 MI.setDesc(
TII.get(TargetOpcode::G_ADD));
1450 MRI->setType(DstReg, sXLen);
1453 case TargetOpcode::G_PTRMASK: {
1456 replacePtrWithInt(
MI.getOperand(1));
1457 MI.setDesc(
TII.get(TargetOpcode::G_AND));
1458 MRI->setType(DstReg, sXLen);
1464void RISCVInstructionSelector::renderNegImm(MachineInstrBuilder &MIB,
1465 const MachineInstr &
MI,
1467 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
1468 "Expected G_CONSTANT");
1469 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
1473void RISCVInstructionSelector::renderImmSubFromXLen(MachineInstrBuilder &MIB,
1474 const MachineInstr &
MI,
1476 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
1477 "Expected G_CONSTANT");
1478 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
1482void RISCVInstructionSelector::renderImmSubFrom32(MachineInstrBuilder &MIB,
1483 const MachineInstr &
MI,
1485 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
1486 "Expected G_CONSTANT");
1487 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
1491void RISCVInstructionSelector::renderImmPlus1(MachineInstrBuilder &MIB,
1492 const MachineInstr &
MI,
1494 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
1495 "Expected G_CONSTANT");
1496 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
1500void RISCVInstructionSelector::renderFrameIndex(MachineInstrBuilder &MIB,
1501 const MachineInstr &
MI,
1503 assert(
MI.getOpcode() == TargetOpcode::G_FRAME_INDEX &&
OpIdx == -1 &&
1504 "Expected G_FRAME_INDEX");
1505 MIB.
add(
MI.getOperand(1));
1508void RISCVInstructionSelector::renderTrailingZeros(MachineInstrBuilder &MIB,
1509 const MachineInstr &
MI,
1511 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
1512 "Expected G_CONSTANT");
1513 uint64_t
C =
MI.getOperand(1).getCImm()->getZExtValue();
1517void RISCVInstructionSelector::renderXLenSubTrailingOnes(
1518 MachineInstrBuilder &MIB,
const MachineInstr &
MI,
int OpIdx)
const {
1519 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
1520 "Expected G_CONSTANT");
1521 uint64_t
C =
MI.getOperand(1).getCImm()->getZExtValue();
1525void RISCVInstructionSelector::renderAddiPairImmSmall(MachineInstrBuilder &MIB,
1526 const MachineInstr &
MI,
1528 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
1529 "Expected G_CONSTANT");
1530 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
1531 int64_t Adj =
Imm < 0 ? -2048 : 2047;
1535void RISCVInstructionSelector::renderAddiPairImmLarge(MachineInstrBuilder &MIB,
1536 const MachineInstr &
MI,
1538 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
1539 "Expected G_CONSTANT");
1540 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue() < 0 ? -2048 : 2047;
1544const TargetRegisterClass *RISCVInstructionSelector::getRegClassForTypeOnBank(
1545 LLT Ty,
const RegisterBank &RB)
const {
1546 if (RB.
getID() == RISCV::GPRBRegBankID) {
1548 return &RISCV::GPRRegClass;
1551 if (RB.
getID() == RISCV::FPRBRegBankID) {
1553 return &RISCV::FPR16RegClass;
1555 return &RISCV::FPR32RegClass;
1557 return &RISCV::FPR64RegClass;
1560 if (RB.
getID() == RISCV::VRBRegBankID) {
1562 return &RISCV::VRRegClass;
1565 return &RISCV::VRM2RegClass;
1568 return &RISCV::VRM4RegClass;
1571 return &RISCV::VRM8RegClass;
1577bool RISCVInstructionSelector::isRegInGprb(
Register Reg)
const {
1581bool RISCVInstructionSelector::isRegInFprb(
Register Reg)
const {
1585bool RISCVInstructionSelector::selectCopy(MachineInstr &
MI)
const {
1591 const TargetRegisterClass *DstRC = getRegClassForTypeOnBank(
1594 "Register class not available for LLT, register bank combination");
1605 MI.setDesc(
TII.get(RISCV::COPY));
1609bool RISCVInstructionSelector::selectImplicitDef(MachineInstr &
MI)
const {
1610 assert(
MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
1612 const Register DstReg =
MI.getOperand(0).getReg();
1613 const TargetRegisterClass *DstRC = getRegClassForTypeOnBank(
1617 "Register class not available for LLT, register bank combination");
1623 MI.setDesc(
TII.get(TargetOpcode::IMPLICIT_DEF));
1627bool RISCVInstructionSelector::materializeImm(
Register DstReg, int64_t Imm,
1628 MachineInstr &
MI)
const {
1629 MachineBasicBlock &
MBB = *
MI.getParent();
1639 unsigned NumInsts = Seq.
size();
1642 for (
unsigned i = 0; i < NumInsts; i++) {
1644 ?
MRI->createVirtualRegister(&RISCV::GPRRegClass)
1646 const RISCVMatInt::Inst &
I = Seq[i];
1649 switch (
I.getOpndKind()) {
1681bool RISCVInstructionSelector::selectAddr(MachineInstr &
MI,
bool IsLocal,
1682 bool IsExternWeak)
const {
1683 assert((
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
1684 MI.getOpcode() == TargetOpcode::G_JUMP_TABLE ||
1685 MI.getOpcode() == TargetOpcode::G_CONSTANT_POOL) &&
1686 "Unexpected opcode");
1688 const MachineOperand &DispMO =
MI.getOperand(1);
1691 const LLT DefTy =
MRI->getType(DefReg);
1698 if (IsLocal && !Subtarget->allowTaggedGlobals()) {
1702 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1711 MachineFunction &MF = *
MI.getParent()->getParent();
1719 TII.get(RISCV::PseudoLGA), DefReg)
1725 MI.eraseFromParent();
1732 "Unsupported code model for lowering",
MI);
1739 Register AddrHiDest =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1740 MachineInstr *AddrHi =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1741 TII.get(RISCV::LUI), AddrHiDest)
1747 TII.get(RISCV::ADDI), DefReg)
1753 MI.eraseFromParent();
1766 MachineFunction &MF = *
MI.getParent()->getParent();
1774 TII.get(RISCV::PseudoLGA), DefReg)
1780 MI.eraseFromParent();
1787 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1795bool RISCVInstructionSelector::selectSelect(MachineInstr &
MI)
const {
1802 Register DstReg = SelectMI.getReg(0);
1804 unsigned Opc = RISCV::Select_GPR_Using_CC_GPR;
1806 unsigned Size =
MRI->getType(DstReg).getSizeInBits();
1807 Opc =
Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR
1808 : RISCV::Select_FPR64_Using_CC_GPR;
1817 .
addReg(SelectMI.getTrueReg())
1818 .
addReg(SelectMI.getFalseReg());
1819 MI.eraseFromParent();
1831 return Size == 16 ? RISCV::FLT_H :
Size == 32 ? RISCV::FLT_S : RISCV::FLT_D;
1833 return Size == 16 ? RISCV::FLE_H :
Size == 32 ? RISCV::FLE_S : RISCV::FLE_D;
1835 return Size == 16 ? RISCV::FEQ_H :
Size == 32 ? RISCV::FEQ_S : RISCV::FEQ_D;
1848 assert(!isLegalFCmpPredicate(Pred) &&
"Predicate already legal?");
1851 if (isLegalFCmpPredicate(InvPred)) {
1859 if (isLegalFCmpPredicate(InvPred)) {
1864 if (isLegalFCmpPredicate(InvPred)) {
1876bool RISCVInstructionSelector::selectFPCompare(MachineInstr &
MI)
const {
1884 unsigned Size =
MRI->getType(
LHS).getSizeInBits();
1889 bool NeedInvert =
false;
1893 TmpReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1902 Register Cmp1Reg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1903 MachineInstr *Cmp1 =
1909 Register Cmp2Reg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1910 MachineInstr *Cmp2 =
1917 TmpReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1919 TII.get(RISCV::OR), TmpReg)
1927 Register Cmp1Reg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1928 MachineInstr *Cmp1 =
1934 Register Cmp2Reg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1935 MachineInstr *Cmp2 =
1942 TmpReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1944 TII.get(RISCV::AND), TmpReg)
1954 TII.get(RISCV::XORI), DstReg)
1960 MI.eraseFromParent();
1964void RISCVInstructionSelector::emitFence(
AtomicOrdering FenceOrdering,
1966 MachineInstr &
MI)
const {
1967 MachineBasicBlock &
MBB = *
MI.getParent();
1970 if (STI.hasStdExtZtso()) {
1973 if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
1997 unsigned Pred, Succ;
1998 switch (FenceOrdering) {
2001 case AtomicOrdering::AcquireRelease:
2005 case AtomicOrdering::Acquire:
2010 case AtomicOrdering::Release:
2015 case AtomicOrdering::SequentiallyConsistent:
2025InstructionSelector *
2029 return new RISCVInstructionSelector(TM, Subtarget, RBI);
unsigned const MachineRegisterInfo * MRI
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool selectUnmergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Provides analysis for querying information about KnownBits during GISel passes.
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
const HexagonInstrInfo * TII
static bool hasAllWUsers(const MachineInstr &OrigMI, const LoongArchSubtarget &ST, const MachineRegisterInfo &MRI)
static bool hasAllNBitUsers(const MachineInstr &OrigMI, const LoongArchSubtarget &ST, const MachineRegisterInfo &MRI, unsigned OrigBits)
Contains matchers for matching SSA Machine Instructions.
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
MachineInstr unsigned OpIdx
static StringRef getName(Value *V)
static unsigned selectRegImmLoadStoreOp(unsigned GenericOpc, unsigned OpSize)
Select the RISC-V regimm opcode for the G_LOAD or G_STORE operation GenericOpc, appropriate for the G...
static unsigned selectZalasrLoadStoreOp(unsigned GenericOpc, unsigned OpSize)
Select the RISC-V Zalasr opcode for the G_LOAD or G_STORE operation GenericOpc, appropriate for the G...
static unsigned getFCmpOpcode(CmpInst::Predicate Pred, unsigned Size)
static bool legalizeFCmpPredicate(Register &LHS, Register &RHS, CmpInst::Predicate &Pred, bool &NeedInvert)
static void getOperandsForBranch(Register CondReg, RISCVCC::CondCode &CC, Register &LHS, Register &RHS, MachineRegisterInfo &MRI)
const SmallVectorImpl< MachineOperand > & Cond
This file declares the targeting of the RegisterBankInfo class for RISC-V.
APInt bitcastToAPInt() const
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)
Constructs an APInt value that has a contiguous range of bits set.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ ICMP_ULT
unsigned less than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ ICMP_SGE
signed greater or equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
This is an important base class in LLVM.
virtual void setupMF(MachineFunction &mf, GISelValueTracking *vt, CodeGenCoverage *covinfo=nullptr, ProfileSummaryInfo *psi=nullptr, BlockFrequencyInfo *bfi=nullptr)
Setup per-MF executor state.
Register getPointerReg() const
Get the source register of the pointer value.
MachineMemOperand & getMMO() const
Get the MachineMemOperand on this instruction.
LocationSize getMemSizeInBits() const
Returns the size in bits of the memory access.
Register getReg(unsigned Idx) const
Access the Idx'th operand as a register and return it.
constexpr unsigned getScalarSizeInBits() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr bool isValid() const
constexpr bool isVector() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr bool isPointer() const
constexpr unsigned getAddressSpace() const
TypeSize getValue() const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addDisp(const MachineOperand &Disp, int64_t off, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
unsigned getOperandNo(const_mop_iterator I) const
Returns the number of the operand iterator I points to.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
AtomicOrdering getSuccessOrdering() const
Return the atomic ordering requirements for this memory operation.
MachineOperand class - Representation of each machine instruction operand.
const ConstantInt * getCImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Analysis providing profile information.
This class provides the information for the target register banks.
std::optional< unsigned > getRealVLen() const
static std::pair< unsigned, unsigned > decomposeSubvectorInsertExtractToSubRegs(MVT VecVT, MVT SubVecVT, unsigned InsertExtractIdx, const RISCVRegisterInfo *TRI)
static unsigned getRegClassIDForVecVT(MVT VT)
static RISCVVType::VLMUL getLMUL(MVT VT)
static const TargetRegisterClass * constrainGenericRegister(Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI)
Constrain the (possibly generic) virtual register Reg to RC.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
This class implements the register bank concept.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
bool isPositionIndependent() const
CodeModel::Model getCodeModel() const
Returns the code model.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
operand_type_match m_Reg()
SpecificConstantMatch m_SpecificICst(const APInt &RequestedValue)
Matches a constant equal to RequestedValue.
operand_type_match m_Pred()
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
ConstantMatch< APInt > m_ICst(APInt &Cst)
BinaryOp_match< LHS, RHS, TargetOpcode::G_ADD, true > m_GAdd(const LHS &L, const RHS &R)
OneNonDBGUse_match< SubPat > m_OneNonDBGUse(const SubPat &SP)
CompareOp_match< Pred, LHS, RHS, TargetOpcode::G_ICMP > m_GICmp(const Pred &P, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SUB > m_GSub(const LHS &L, const RHS &R)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SHL, false > m_GShl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_AND, true > m_GAnd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_LSHR, false > m_GLShr(const LHS &L, const RHS &R)
unsigned getBrCond(CondCode CC, unsigned SelectOpc=0)
InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI)
SmallVector< Inst, 8 > InstSeq
static unsigned decodeVSEW(unsigned VSEW)
LLVM_ABI unsigned getSEWLMULRatio(unsigned SEW, VLMUL VLMul)
LLVM_ABI unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic, bool AltFmt=false)
static constexpr int64_t VLMaxSentinel
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
@ System
Synchronized with respect to all concurrently executing threads.
This is an optimization pass for GlobalISel generic memory operations.
PointerUnion< const TargetRegisterClass *, const RegisterBank * > RegClassOrRegBank
Convenient type to represent either a register class or a register bank.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isStrongerThanMonotonic(AtomicOrdering AO)
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
LLVM_ABI void constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
LLVM_ABI MVT getMVTForLLT(LLT Ty)
Get a rough equivalent of an MVT for a given LLT.
InstructionSelector * createRISCVInstructionSelector(const RISCVTargetMachine &TM, const RISCVSubtarget &Subtarget, const RISCVRegisterBankInfo &RBI)
LLVM_ABI std::optional< int64_t > getIConstantVRegSExtVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT fits in int64_t returns it.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void reportGISelFailure(MachineFunction &MF, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel error as a missed optimization remark to the LLVMContext's diagnostic stream.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
AtomicOrdering
Atomic ordering for LLVM's memory model.
constexpr T maskTrailingZeros(unsigned N)
Create a bitmask with the N right-most bits set to 0, and all other bits set to 1.
@ Or
Bitwise or logical OR of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI std::optional< ValueAndVReg > getIConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs=true)
If VReg is defined by a statically evaluable chain of instructions rooted on a G_CONSTANT returns its...
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.