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
57 static constexpr unsigned MaxRecursionDepth = 6;
60 const unsigned Depth = 0)
const;
86 bool IsExternWeak =
false)
const;
94 unsigned &CurOp,
bool IsMasked,
95 bool IsStridedOrIndexed,
96 LLT *IndexVT =
nullptr)
const;
102 unsigned ShiftWidth)
const;
103 ComplexRendererFns selectShiftMaskXLen(
MachineOperand &Root)
const {
104 return selectShiftMask(Root, STI.
getXLen());
106 ComplexRendererFns selectShiftMask32(
MachineOperand &Root)
const {
107 return selectShiftMask(Root, 32);
111 ComplexRendererFns selectSExtBits(
MachineOperand &Root,
unsigned Bits)
const;
112 template <
unsigned Bits>
114 return selectSExtBits(Root, Bits);
117 ComplexRendererFns selectZExtBits(
MachineOperand &Root,
unsigned Bits)
const;
118 template <
unsigned Bits>
120 return selectZExtBits(Root, Bits);
123 ComplexRendererFns selectSHXADDOp(
MachineOperand &Root,
unsigned ShAmt)
const;
124 template <
unsigned ShAmt>
126 return selectSHXADDOp(Root, ShAmt);
130 unsigned ShAmt)
const;
131 template <
unsigned ShAmt>
132 ComplexRendererFns selectSHXADD_UWOp(
MachineOperand &Root)
const {
133 return selectSHXADD_UWOp(Root, ShAmt);
171#define GET_GLOBALISEL_PREDICATES_DECL
172#include "RISCVGenGlobalISel.inc"
173#undef GET_GLOBALISEL_PREDICATES_DECL
175#define GET_GLOBALISEL_TEMPORARIES_DECL
176#include "RISCVGenGlobalISel.inc"
177#undef GET_GLOBALISEL_TEMPORARIES_DECL
182#define GET_GLOBALISEL_IMPL
183#include "RISCVGenGlobalISel.inc"
184#undef GET_GLOBALISEL_IMPL
186RISCVInstructionSelector::RISCVInstructionSelector(
189 : STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()), RBI(RBI),
193#include
"RISCVGenGlobalISel.inc"
196#include
"RISCVGenGlobalISel.inc"
202bool RISCVInstructionSelector::hasAllNBitUsers(
const MachineInstr &
MI,
204 const unsigned Depth)
const {
206 assert((
MI.getOpcode() == TargetOpcode::G_ADD ||
207 MI.getOpcode() == TargetOpcode::G_SUB ||
208 MI.getOpcode() == TargetOpcode::G_MUL ||
209 MI.getOpcode() == TargetOpcode::G_SHL ||
210 MI.getOpcode() == TargetOpcode::G_LSHR ||
211 MI.getOpcode() == TargetOpcode::G_AND ||
212 MI.getOpcode() == TargetOpcode::G_OR ||
213 MI.getOpcode() == TargetOpcode::G_XOR ||
214 MI.getOpcode() == TargetOpcode::G_SEXT_INREG ||
Depth != 0) &&
215 "Unexpected opcode");
217 if (
Depth >= RISCVInstructionSelector::MaxRecursionDepth)
220 auto DestReg =
MI.getOperand(0).getReg();
222 assert(UserOp.getParent() &&
"UserOp must have a parent");
223 const MachineInstr &UserMI = *UserOp.getParent();
232 case RISCV::FCVT_D_W:
233 case RISCV::FCVT_S_W:
276InstructionSelector::ComplexRendererFns
277RISCVInstructionSelector::selectShiftMask(MachineOperand &Root,
278 unsigned ShiftWidth)
const {
282 using namespace llvm::MIPatternMatch;
288 ShAmtReg = ZExtSrcReg;
307 APInt ShMask(AndMask.
getBitWidth(), ShiftWidth - 1);
308 if (ShMask.isSubsetOf(AndMask)) {
309 ShAmtReg = AndSrcReg;
313 KnownBits
Known = VT->getKnownBits(AndSrcReg);
314 if (ShMask.isSubsetOf(AndMask |
Known.Zero))
315 ShAmtReg = AndSrcReg;
322 if (Imm != 0 &&
Imm.urem(ShiftWidth) == 0)
327 if (Imm != 0 &&
Imm.urem(ShiftWidth) == 0) {
331 unsigned NegOpc = Subtarget->
is64Bit() ? RISCV::SUBW : RISCV::SUB;
332 return {{[=](MachineInstrBuilder &MIB) {
333 MachineIRBuilder(*MIB.getInstr())
334 .buildInstr(NegOpc, {ShAmtReg}, {
Register(RISCV::X0),
Reg});
335 MIB.addReg(ShAmtReg);
338 if (
Imm.urem(ShiftWidth) == ShiftWidth - 1) {
342 return {{[=](MachineInstrBuilder &MIB) {
343 MachineIRBuilder(*MIB.getInstr())
344 .buildInstr(RISCV::XORI, {ShAmtReg}, {
Reg})
346 MIB.addReg(ShAmtReg);
351 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(ShAmtReg); }}};
354InstructionSelector::ComplexRendererFns
355RISCVInstructionSelector::selectSExtBits(MachineOperand &Root,
356 unsigned Bits)
const {
360 MachineInstr *RootDef = MRI->
getVRegDef(RootReg);
362 if (RootDef->
getOpcode() == TargetOpcode::G_SEXT_INREG &&
365 {[=](MachineInstrBuilder &MIB) { MIB.add(RootDef->
getOperand(1)); }}};
369 if ((
Size - VT->computeNumSignBits(RootReg)) < Bits)
370 return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
375InstructionSelector::ComplexRendererFns
376RISCVInstructionSelector::selectZExtBits(MachineOperand &Root,
377 unsigned Bits)
const {
385 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}};
390 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}};
394 return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
399InstructionSelector::ComplexRendererFns
400RISCVInstructionSelector::selectSHXADDOp(MachineOperand &Root,
401 unsigned ShAmt)
const {
402 using namespace llvm::MIPatternMatch;
408 const unsigned XLen = STI.
getXLen();
427 if (
Mask.isShiftedMask()) {
428 unsigned Leading = XLen -
Mask.getActiveBits();
429 unsigned Trailing =
Mask.countr_zero();
432 if (*LeftShift && Leading == 0 && C2.
ult(Trailing) && Trailing == ShAmt) {
434 return {{[=](MachineInstrBuilder &MIB) {
435 MachineIRBuilder(*MIB.getInstr())
436 .buildInstr(RISCV::SRLI, {DstReg}, {RegY})
444 if (!*LeftShift && Leading == C2 && Trailing == ShAmt) {
446 return {{[=](MachineInstrBuilder &MIB) {
447 MachineIRBuilder(*MIB.getInstr())
448 .buildInstr(RISCV::SRLI, {DstReg}, {RegY})
449 .addImm(Leading + Trailing);
470 unsigned Leading = XLen -
Mask.getActiveBits();
471 unsigned Trailing =
Mask.countr_zero();
485 return {{[=](MachineInstrBuilder &MIB) {
486 MachineIRBuilder(*MIB.getInstr())
487 .buildInstr(RISCV::SRLIW, {DstReg}, {RegY})
497InstructionSelector::ComplexRendererFns
498RISCVInstructionSelector::selectSHXADD_UWOp(MachineOperand &Root,
499 unsigned ShAmt)
const {
500 using namespace llvm::MIPatternMatch;
517 if (
Mask.isShiftedMask()) {
518 unsigned Leading =
Mask.countl_zero();
519 unsigned Trailing =
Mask.countr_zero();
520 if (Leading == 32 - ShAmt && C2 == Trailing && Trailing > ShAmt) {
522 return {{[=](MachineInstrBuilder &MIB) {
523 MachineIRBuilder(*MIB.getInstr())
524 .buildInstr(RISCV::SLLI, {DstReg}, {RegX})
535InstructionSelector::ComplexRendererFns
536RISCVInstructionSelector::renderVLOp(MachineOperand &Root)
const {
537 assert(Root.
isReg() &&
"Expected operand to be a Register");
540 if (RootDef->
getOpcode() == TargetOpcode::G_CONSTANT) {
542 if (
C->getValue().isAllOnes())
546 return {{[=](MachineInstrBuilder &MIB) {
551 uint64_t ZExtC =
C->getZExtValue();
552 return {{[=](MachineInstrBuilder &MIB) { MIB.addImm(ZExtC); }}};
555 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.
getReg()); }}};
558InstructionSelector::ComplexRendererFns
559RISCVInstructionSelector::selectAddrRegImm(MachineOperand &Root)
const {
564 if (RootDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX) {
566 [=](MachineInstrBuilder &MIB) { MIB.add(RootDef->
getOperand(1)); },
567 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
571 if (isBaseWithConstantOffset(Root, *MRI)) {
579 if (LHSDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX)
581 [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->
getOperand(1)); },
582 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
585 return {{[=](MachineInstrBuilder &MIB) { MIB.add(
LHS); },
586 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }}};
592 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.
getReg()); },
593 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
602 case CmpInst::Predicate::ICMP_EQ:
604 case CmpInst::Predicate::ICMP_NE:
606 case CmpInst::Predicate::ICMP_ULT:
608 case CmpInst::Predicate::ICMP_SLT:
610 case CmpInst::Predicate::ICMP_UGE:
612 case CmpInst::Predicate::ICMP_SGE:
678 CC = getRISCVCCFromICmp(Pred);
685 const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
690 return IsStore ? RISCV::SB_RL : RISCV::LB_AQ;
692 return IsStore ? RISCV::SH_RL : RISCV::LH_AQ;
694 return IsStore ? RISCV::SW_RL : RISCV::LW_AQ;
696 return IsStore ? RISCV::SD_RL : RISCV::LD_AQ;
704 const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
708 return IsStore ? RISCV::SB : RISCV::LBU;
710 return IsStore ? RISCV::SH : RISCV::LH;
712 return IsStore ? RISCV::SW : RISCV::LW;
714 return IsStore ? RISCV::SD : RISCV::LD;
720void RISCVInstructionSelector::addVectorLoadStoreOperands(
721 MachineInstr &
I, SmallVectorImpl<Register> &SrcOps,
unsigned &CurOp,
722 bool IsMasked,
bool IsStridedOrIndexed, LLT *IndexVT)
const {
724 auto PtrReg =
I.getOperand(CurOp++).getReg();
728 if (IsStridedOrIndexed) {
729 auto StrideReg =
I.getOperand(CurOp++).getReg();
732 *IndexVT = MRI->
getType(StrideReg);
737 auto MaskReg =
I.getOperand(CurOp++).getReg();
742bool RISCVInstructionSelector::selectIntrinsicWithSideEffects(
743 MachineInstr &
I)
const {
750 case Intrinsic::riscv_vlm:
751 case Intrinsic::riscv_vle:
752 case Intrinsic::riscv_vle_mask:
753 case Intrinsic::riscv_vlse:
754 case Intrinsic::riscv_vlse_mask: {
755 bool IsMasked = IntrinID == Intrinsic::riscv_vle_mask ||
756 IntrinID == Intrinsic::riscv_vlse_mask;
757 bool IsStrided = IntrinID == Intrinsic::riscv_vlse ||
758 IntrinID == Intrinsic::riscv_vlse_mask;
759 LLT VT = MRI->
getType(
I.getOperand(0).getReg());
763 const Register DstReg =
I.getOperand(0).getReg();
766 bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
771 if (HasPassthruOperand) {
772 auto PassthruReg =
I.getOperand(CurOp++).getReg();
778 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked, IsStrided);
781 const RISCV::VLEPseudo *
P =
782 RISCV::getVLEPseudo(IsMasked, IsStrided,
false, Log2SEW,
783 static_cast<unsigned>(LMUL));
785 MachineInstrBuilder PseudoMI =
786 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(
P->Pseudo), DstReg);
791 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
792 for (
auto &RenderFn : *VLOpFn)
801 Policy =
I.getOperand(CurOp++).getImm();
811 case Intrinsic::riscv_vloxei:
812 case Intrinsic::riscv_vloxei_mask:
813 case Intrinsic::riscv_vluxei:
814 case Intrinsic::riscv_vluxei_mask: {
815 bool IsMasked = IntrinID == Intrinsic::riscv_vloxei_mask ||
816 IntrinID == Intrinsic::riscv_vluxei_mask;
817 bool IsOrdered = IntrinID == Intrinsic::riscv_vloxei ||
818 IntrinID == Intrinsic::riscv_vloxei_mask;
819 LLT VT = MRI->
getType(
I.getOperand(0).getReg());
823 const Register DstReg =
I.getOperand(0).getReg();
826 bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
831 if (HasPassthruOperand) {
832 auto PassthruReg =
I.getOperand(CurOp++).getReg();
839 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked,
true, &IndexVT);
845 if (IndexLog2EEW == 6 && !Subtarget->
is64Bit()) {
847 "values when XLEN=32");
849 const RISCV::VLX_VSXPseudo *
P = RISCV::getVLXPseudo(
850 IsMasked, IsOrdered, IndexLog2EEW,
static_cast<unsigned>(LMUL),
851 static_cast<unsigned>(IndexLMUL));
853 MachineInstrBuilder PseudoMI =
854 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(
P->Pseudo), DstReg);
859 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
860 for (
auto &RenderFn : *VLOpFn)
869 Policy =
I.getOperand(CurOp++).getImm();
879 case Intrinsic::riscv_vsm:
880 case Intrinsic::riscv_vse:
881 case Intrinsic::riscv_vse_mask:
882 case Intrinsic::riscv_vsse:
883 case Intrinsic::riscv_vsse_mask: {
884 bool IsMasked = IntrinID == Intrinsic::riscv_vse_mask ||
885 IntrinID == Intrinsic::riscv_vsse_mask;
886 bool IsStrided = IntrinID == Intrinsic::riscv_vsse ||
887 IntrinID == Intrinsic::riscv_vsse_mask;
888 LLT VT = MRI->
getType(
I.getOperand(1).getReg());
896 auto PassthruReg =
I.getOperand(CurOp++).getReg();
899 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked, IsStrided);
902 const RISCV::VSEPseudo *
P = RISCV::getVSEPseudo(
903 IsMasked, IsStrided, Log2SEW,
static_cast<unsigned>(LMUL));
905 MachineInstrBuilder PseudoMI =
911 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
912 for (
auto &RenderFn : *VLOpFn)
925 case Intrinsic::riscv_vsoxei:
926 case Intrinsic::riscv_vsoxei_mask:
927 case Intrinsic::riscv_vsuxei:
928 case Intrinsic::riscv_vsuxei_mask: {
929 bool IsMasked = IntrinID == Intrinsic::riscv_vsoxei_mask ||
930 IntrinID == Intrinsic::riscv_vsuxei_mask;
931 bool IsOrdered = IntrinID == Intrinsic::riscv_vsoxei ||
932 IntrinID == Intrinsic::riscv_vsoxei_mask;
933 LLT VT = MRI->
getType(
I.getOperand(1).getReg());
941 auto PassthruReg =
I.getOperand(CurOp++).getReg();
945 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked,
true, &IndexVT);
951 if (IndexLog2EEW == 6 && !Subtarget->
is64Bit()) {
953 "values when XLEN=32");
955 const RISCV::VLX_VSXPseudo *
P = RISCV::getVSXPseudo(
956 IsMasked, IsOrdered, IndexLog2EEW,
static_cast<unsigned>(LMUL),
957 static_cast<unsigned>(IndexLMUL));
959 MachineInstrBuilder PseudoMI =
965 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
966 for (
auto &RenderFn : *VLOpFn)
982bool RISCVInstructionSelector::selectIntrinsic(MachineInstr &
I)
const {
989 case Intrinsic::riscv_vsetvli:
990 case Intrinsic::riscv_vsetvlimax: {
992 bool VLMax = IntrinID == Intrinsic::riscv_vsetvlimax;
994 unsigned Offset = VLMax ? 2 : 3;
1002 Register DstReg =
I.getOperand(0).getReg();
1005 unsigned Opcode = RISCV::PseudoVSETVLI;
1009 Register AVLReg =
I.getOperand(2).getReg();
1011 uint64_t AVL = AVLConst->Value.getZExtValue();
1018 MachineInstr *AVLDef = MRI->
getVRegDef(AVLReg);
1019 if (AVLDef && AVLDef->
getOpcode() == TargetOpcode::G_CONSTANT) {
1021 if (
C->getValue().isAllOnes())
1028 Opcode = RISCV::PseudoVSETVLIX0;
1030 Register AVLReg =
I.getOperand(2).getReg();
1035 uint64_t AVL = AVLConst->Value.getZExtValue();
1037 MachineInstr *PseudoMI =
1039 TII.get(RISCV::PseudoVSETIVLI), DstReg)
1042 I.eraseFromParent();
1049 MachineInstr *PseudoMI =
1050 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode), DstReg)
1053 I.eraseFromParent();
1060bool RISCVInstructionSelector::selectExtractSubvector(MachineInstr &
MI)
const {
1061 assert(
MI.getOpcode() == TargetOpcode::G_EXTRACT_SUBVECTOR);
1066 LLT DstTy = MRI->
getType(DstReg);
1067 LLT SrcTy = MRI->
getType(SrcReg);
1069 unsigned Idx =
static_cast<unsigned>(
MI.getOperand(2).
getImm());
1075 std::tie(SubRegIdx, Idx) =
1077 SrcMVT, DstMVT, Idx, &
TRI);
1092 BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1094 .
addReg(SrcReg, {}, SubRegIdx);
1096 MI.eraseFromParent();
1100bool RISCVInstructionSelector::selectInsertSubVector(MachineInstr &
MI)
const {
1101 assert(
MI.getOpcode() == TargetOpcode::G_INSERT_SUBVECTOR);
1105 Register SubVecReg =
MI.getOperand(2).getReg();
1107 LLT VecTy = MRI->
getType(VecReg);
1108 LLT SubVecTy = MRI->
getType(SubVecReg);
1113 unsigned Idx =
static_cast<unsigned>(
MI.getOperand(3).
getImm());
1116 std::tie(SubRegIdx, Idx) =
1118 VecMVT, SubVecMVT, Idx, &
TRI);
1134 if (SubRegIdx == RISCV::NoSubRegister) {
1137 "Unexpected subvector insert");
1138 BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1141 MI.eraseFromParent();
1147 MachineInstr *Ins =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1148 TII.get(TargetOpcode::INSERT_SUBREG), DstReg)
1153 MI.eraseFromParent();
1158bool RISCVInstructionSelector::select(MachineInstr &
MI) {
1160 const unsigned Opc =
MI.getOpcode();
1162 if (!
MI.isPreISelOpcode() ||
Opc == TargetOpcode::G_PHI) {
1163 if (
Opc == TargetOpcode::PHI ||
Opc == TargetOpcode::G_PHI) {
1164 const Register DefReg =
MI.getOperand(0).getReg();
1165 const LLT DefTy = MRI->
getType(DefReg);
1179 DefRC =
TRI.getRegClassForTypeOnBank(DefTy, RB, STI.
is64Bit());
1186 MI.setDesc(
TII.get(TargetOpcode::PHI));
1197 if (selectImpl(
MI, *CoverageInfo))
1201 case TargetOpcode::G_ANYEXT:
1202 case TargetOpcode::G_PTRTOINT:
1203 case TargetOpcode::G_INTTOPTR:
1204 case TargetOpcode::G_TRUNC:
1205 case TargetOpcode::G_FREEZE:
1207 case TargetOpcode::G_CONSTANT: {
1209 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
1211 if (!materializeImm(DstReg, Imm,
MI))
1214 MI.eraseFromParent();
1217 case TargetOpcode::G_ZEXT:
1218 case TargetOpcode::G_SEXT: {
1219 bool IsSigned =
Opc != TargetOpcode::G_ZEXT;
1222 LLT SrcTy = MRI->
getType(SrcReg);
1229 RISCV::GPRBRegBankID &&
1230 "Unexpected ext regbank");
1233 if (IsSigned && SrcSize == 32) {
1234 MI.setDesc(
TII.get(RISCV::ADDIW));
1241 if (!IsSigned && SrcSize == 32 && STI.hasStdExtZba()) {
1242 MI.setDesc(
TII.get(RISCV::ADD_UW));
1249 if (SrcSize == 16 &&
1250 (STI.hasStdExtZbb() || (!IsSigned && STI.hasStdExtZbkb()))) {
1251 MI.setDesc(
TII.get(IsSigned ? RISCV::SEXT_H
1252 : STI.isRV64() ? RISCV::ZEXT_H_RV64
1253 : RISCV::ZEXT_H_RV32));
1260 MachineInstr *ShiftLeft =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1261 TII.get(RISCV::SLLI), ShiftLeftReg)
1265 MachineInstr *ShiftRight =
1267 TII.get(IsSigned ? RISCV::SRAI : RISCV::SRLI), DstReg)
1271 MI.eraseFromParent();
1274 case TargetOpcode::G_FCONSTANT: {
1277 const APFloat &FPimm =
MI.getOperand(1).getFPImm()->getValueAPF();
1286 if (!materializeImm(GPRReg,
Imm.getSExtValue(),
MI))
1290 unsigned Opcode =
Size == 64 ? RISCV::FMV_D_X
1291 :
Size == 32 ? RISCV::FMV_W_X
1293 MachineInstr *FMV =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1294 TII.get(Opcode), DstReg)
1300 "Unexpected size or subtarget");
1304 MachineInstr *FCVT =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1305 TII.get(RISCV::FCVT_D_W), DstReg)
1310 MI.eraseFromParent();
1318 if (!materializeImm(GPRRegHigh,
Imm.extractBits(32, 32).getSExtValue(),
1321 if (!materializeImm(GPRRegLow,
Imm.trunc(32).getSExtValue(),
MI))
1323 MachineInstr *PairF64 =
1325 TII.get(RISCV::BuildPairF64Pseudo), DstReg)
1331 MI.eraseFromParent();
1334 case TargetOpcode::G_GLOBAL_VALUE: {
1335 auto *GV =
MI.getOperand(1).getGlobal();
1336 if (GV->isThreadLocal()) {
1341 return selectAddr(
MI, GV->isDSOLocal(), GV->hasExternalWeakLinkage());
1343 case TargetOpcode::G_JUMP_TABLE:
1344 case TargetOpcode::G_CONSTANT_POOL:
1345 return selectAddr(
MI);
1346 case TargetOpcode::G_BRCOND: {
1351 MachineInstr *Bcc =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1355 .
addMBB(
MI.getOperand(1).getMBB());
1356 MI.eraseFromParent();
1360 case TargetOpcode::G_BRINDIRECT:
1361 MI.setDesc(
TII.get(RISCV::PseudoBRIND));
1365 case TargetOpcode::G_SELECT:
1366 return selectSelect(
MI);
1367 case TargetOpcode::G_FCMP:
1368 return selectFPCompare(
MI);
1369 case TargetOpcode::G_FENCE: {
1374 emitFence(FenceOrdering, FenceSSID,
MI);
1375 MI.eraseFromParent();
1378 case TargetOpcode::G_IMPLICIT_DEF:
1379 return selectImplicitDef(
MI);
1380 case TargetOpcode::G_UNMERGE_VALUES:
1382 case TargetOpcode::G_LOAD:
1383 case TargetOpcode::G_STORE: {
1387 LLT PtrTy = MRI->
getType(PtrReg);
1389 const RegisterBank &RB = *RBI.
getRegBank(ValReg, *MRI,
TRI);
1390 if (RB.
getID() != RISCV::GPRBRegBankID)
1394 const RegisterBank &PtrRB = *RBI.
getRegBank(PtrReg, *MRI,
TRI);
1397 "Load/Store pointer operand isn't a GPR");
1398 assert(PtrTy.
isPointer() &&
"Load/Store pointer operand isn't a pointer");
1415 if (NewOpc ==
MI.getOpcode())
1419 auto AddrModeFns = selectAddrRegImm(
MI.getOperand(1));
1424 MachineInstrBuilder NewInst =
1432 for (
auto &Fn : *AddrModeFns)
1434 MI.eraseFromParent();
1439 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
1440 return selectIntrinsicWithSideEffects(
MI);
1441 case TargetOpcode::G_INTRINSIC:
1442 return selectIntrinsic(
MI);
1443 case TargetOpcode::G_EXTRACT_SUBVECTOR:
1444 return selectExtractSubvector(
MI);
1445 case TargetOpcode::G_INSERT_SUBVECTOR:
1446 return selectInsertSubVector(
MI);
1452bool RISCVInstructionSelector::selectUnmergeValues(MachineInstr &
MI)
const {
1453 assert(
MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
1455 if (!Subtarget->hasStdExtZfa())
1459 if (
MI.getNumOperands() != 3)
1464 if (!isRegInFprb(Src) || !isRegInGprb(
Lo) || !isRegInGprb(
Hi))
1467 MachineInstr *ExtractLo =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1468 TII.get(RISCV::FMV_X_W_FPR64),
Lo)
1472 MachineInstr *ExtractHi =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1473 TII.get(RISCV::FMVH_X_D),
Hi)
1477 MI.eraseFromParent();
1481bool RISCVInstructionSelector::replacePtrWithInt(MachineOperand &
Op) {
1486 MachineInstr &ParentMI = *
Op.getParent();
1489 MachineInstr *PtrToInt =
1491 TII.get(TargetOpcode::G_PTRTOINT), IntReg)
1494 return select(*PtrToInt);
1497void RISCVInstructionSelector::preISelLower(MachineInstr &
MI) {
1498 switch (
MI.getOpcode()) {
1499 case TargetOpcode::G_PTR_ADD: {
1503 replacePtrWithInt(
MI.getOperand(1));
1504 MI.setDesc(
TII.get(TargetOpcode::G_ADD));
1508 case TargetOpcode::G_PTRMASK: {
1511 replacePtrWithInt(
MI.getOperand(1));
1512 MI.setDesc(
TII.get(TargetOpcode::G_AND));
1519void RISCVInstructionSelector::renderNegImm(MachineInstrBuilder &MIB,
1520 const MachineInstr &
MI,
1522 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
1523 "Expected G_CONSTANT");
1524 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
1528void RISCVInstructionSelector::renderImmSubFromXLen(MachineInstrBuilder &MIB,
1529 const MachineInstr &
MI,
1531 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
1532 "Expected G_CONSTANT");
1533 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
1537void RISCVInstructionSelector::renderImmSubFrom32(MachineInstrBuilder &MIB,
1538 const MachineInstr &
MI,
1540 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
1541 "Expected G_CONSTANT");
1542 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
1546void RISCVInstructionSelector::renderImmPlus1(MachineInstrBuilder &MIB,
1547 const MachineInstr &
MI,
1549 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
1550 "Expected G_CONSTANT");
1551 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
1555void RISCVInstructionSelector::renderTrailingZeros(MachineInstrBuilder &MIB,
1556 const MachineInstr &
MI,
1558 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
1559 "Expected G_CONSTANT");
1560 uint64_t
C =
MI.getOperand(1).getCImm()->getZExtValue();
1564void RISCVInstructionSelector::renderXLenSubTrailingOnes(
1565 MachineInstrBuilder &MIB,
const MachineInstr &
MI,
int OpIdx)
const {
1566 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
1567 "Expected G_CONSTANT");
1568 uint64_t
C =
MI.getOperand(1).getCImm()->getZExtValue();
1572void RISCVInstructionSelector::renderAddiPairImmSmall(MachineInstrBuilder &MIB,
1573 const MachineInstr &
MI,
1575 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
1576 "Expected G_CONSTANT");
1577 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
1578 int64_t Adj =
Imm < 0 ? -2048 : 2047;
1582void RISCVInstructionSelector::renderAddiPairImmLarge(MachineInstrBuilder &MIB,
1583 const MachineInstr &
MI,
1585 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
1586 "Expected G_CONSTANT");
1587 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue() < 0 ? -2048 : 2047;
1591bool RISCVInstructionSelector::isRegInGprb(
Register Reg)
const {
1595bool RISCVInstructionSelector::isRegInFprb(
Register Reg)
const {
1599bool RISCVInstructionSelector::selectCopy(MachineInstr &
MI)
const {
1600 MachineOperand Dst =
MI.getOperand(0);
1607 TRI.getConstrainedRegClassForOperand(Dst, *MRI);
1610 "Register class not available for LLT, register bank combination");
1621 MI.setDesc(
TII.get(RISCV::COPY));
1625bool RISCVInstructionSelector::selectImplicitDef(MachineInstr &
MI)
const {
1626 assert(
MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
1628 const Register DstReg =
MI.getOperand(0).getReg();
1633 "Register class not available for LLT, register bank combination");
1639 MI.setDesc(
TII.get(TargetOpcode::IMPLICIT_DEF));
1643bool RISCVInstructionSelector::materializeImm(
Register DstReg, int64_t Imm,
1644 MachineInstr &
MI)
const {
1645 MachineBasicBlock &
MBB = *
MI.getParent();
1655 unsigned NumInsts = Seq.
size();
1658 for (
unsigned i = 0; i < NumInsts; i++) {
1662 const RISCVMatInt::Inst &
I = Seq[i];
1665 switch (
I.getOpndKind()) {
1697bool RISCVInstructionSelector::selectAddr(MachineInstr &
MI,
bool IsLocal,
1698 bool IsExternWeak)
const {
1699 assert((
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
1700 MI.getOpcode() == TargetOpcode::G_JUMP_TABLE ||
1701 MI.getOpcode() == TargetOpcode::G_CONSTANT_POOL) &&
1702 "Unexpected opcode");
1704 const MachineOperand &DispMO =
MI.getOperand(1);
1707 const LLT DefTy = MRI->
getType(DefReg);
1714 if (IsLocal && !Subtarget->allowTaggedGlobals()) {
1718 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1727 MachineFunction &MF = *
MI.getParent()->getParent();
1735 TII.get(RISCV::PseudoLGA), DefReg)
1741 MI.eraseFromParent();
1748 "Unsupported code model for lowering",
MI);
1756 MachineInstr *AddrHi =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1757 TII.get(RISCV::LUI), AddrHiDest)
1763 TII.get(RISCV::ADDI), DefReg)
1769 MI.eraseFromParent();
1782 MachineFunction &MF = *
MI.getParent()->getParent();
1790 TII.get(RISCV::PseudoLGA), DefReg)
1796 MI.eraseFromParent();
1803 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1811bool RISCVInstructionSelector::selectSelect(MachineInstr &
MI)
const {
1818 Register DstReg = SelectMI.getReg(0);
1820 unsigned Opc = RISCV::Select_GPR_Using_CC_GPR;
1823 Opc =
Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR
1824 : RISCV::Select_FPR64_Using_CC_GPR;
1833 .
addReg(SelectMI.getTrueReg())
1834 .
addReg(SelectMI.getFalseReg());
1835 MI.eraseFromParent();
1847 return Size == 16 ? RISCV::FLT_H :
Size == 32 ? RISCV::FLT_S : RISCV::FLT_D;
1849 return Size == 16 ? RISCV::FLE_H :
Size == 32 ? RISCV::FLE_S : RISCV::FLE_D;
1851 return Size == 16 ? RISCV::FEQ_H :
Size == 32 ? RISCV::FEQ_S : RISCV::FEQ_D;
1864 assert(!isLegalFCmpPredicate(Pred) &&
"Predicate already legal?");
1867 if (isLegalFCmpPredicate(InvPred)) {
1875 if (isLegalFCmpPredicate(InvPred)) {
1880 if (isLegalFCmpPredicate(InvPred)) {
1892bool RISCVInstructionSelector::selectFPCompare(MachineInstr &
MI)
const {
1905 bool NeedInvert =
false;
1919 MachineInstr *Cmp1 =
1926 MachineInstr *Cmp2 =
1935 TII.get(RISCV::OR), TmpReg)
1954 MachineInstr *Cmp1 =
1961 MachineInstr *Cmp2 =
1968 TII.get(RISCV::AND), TmpReg)
1979 TII.get(RISCV::XORI), DstReg)
1985 MI.eraseFromParent();
1989void RISCVInstructionSelector::emitFence(
AtomicOrdering FenceOrdering,
1991 MachineInstr &
MI)
const {
1992 MachineBasicBlock &
MBB = *
MI.getParent();
1995 if (STI.hasStdExtZtso()) {
1998 if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
2022 unsigned Pred, Succ;
2023 switch (FenceOrdering) {
2026 case AtomicOrdering::AcquireRelease:
2030 case AtomicOrdering::Acquire:
2035 case AtomicOrdering::Release:
2040 case AtomicOrdering::SequentiallyConsistent:
2050InstructionSelector *
2054 return new RISCVInstructionSelector(TM, Subtarget, RBI);
#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
uint64_t getZExtValue() const
Get zero extended value.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
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 & 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,...
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
const RegClassOrRegBank & getRegClassOrRegBank(Register Reg) const
Return the register bank or register class of Reg.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
LLVM_ABI void setRegBank(Register Reg, const RegisterBank &RegBank)
Set the register bank to RegBank for Reg.
LLVM_ABI void setType(Register VReg, LLT Ty)
Set the low-level type of VReg to Ty.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
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.
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.
#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.
@ Known
Known to have no common set bits.
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.
MCRegisterClass TargetRegisterClass
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.