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();
224 unsigned OpIdx = UserOp.getOperandNo();
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 {
364 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(SrcReg); }}};
368 if ((
Size - VT->computeNumSignBits(RootReg)) < Bits)
369 return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
374InstructionSelector::ComplexRendererFns
375RISCVInstructionSelector::selectZExtBits(MachineOperand &Root,
376 unsigned Bits)
const {
384 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}};
389 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}};
393 return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
398InstructionSelector::ComplexRendererFns
399RISCVInstructionSelector::selectSHXADDOp(MachineOperand &Root,
400 unsigned ShAmt)
const {
401 using namespace llvm::MIPatternMatch;
407 const unsigned XLen = STI.
getXLen();
426 if (
Mask.isShiftedMask()) {
427 unsigned Leading = XLen -
Mask.getActiveBits();
428 unsigned Trailing =
Mask.countr_zero();
431 if (*LeftShift && Leading == 0 && C2.
ult(Trailing) && Trailing == ShAmt) {
433 return {{[=](MachineInstrBuilder &MIB) {
434 MachineIRBuilder(*MIB.getInstr())
435 .buildInstr(RISCV::SRLI, {DstReg}, {RegY})
443 if (!*LeftShift && Leading == C2 && Trailing == ShAmt) {
445 return {{[=](MachineInstrBuilder &MIB) {
446 MachineIRBuilder(*MIB.getInstr())
447 .buildInstr(RISCV::SRLI, {DstReg}, {RegY})
448 .addImm(Leading + Trailing);
469 unsigned Leading = XLen -
Mask.getActiveBits();
470 unsigned Trailing =
Mask.countr_zero();
484 return {{[=](MachineInstrBuilder &MIB) {
485 MachineIRBuilder(*MIB.getInstr())
486 .buildInstr(RISCV::SRLIW, {DstReg}, {RegY})
496InstructionSelector::ComplexRendererFns
497RISCVInstructionSelector::selectSHXADD_UWOp(MachineOperand &Root,
498 unsigned ShAmt)
const {
499 using namespace llvm::MIPatternMatch;
516 if (
Mask.isShiftedMask()) {
517 unsigned Leading =
Mask.countl_zero();
518 unsigned Trailing =
Mask.countr_zero();
519 if (Leading == 32 - ShAmt && C2 == Trailing && Trailing > ShAmt) {
521 return {{[=](MachineInstrBuilder &MIB) {
522 MachineIRBuilder(*MIB.getInstr())
523 .buildInstr(RISCV::SLLI, {DstReg}, {RegX})
534InstructionSelector::ComplexRendererFns
535RISCVInstructionSelector::renderVLOp(MachineOperand &Root)
const {
536 assert(Root.
isReg() &&
"Expected operand to be a Register");
537 std::optional<ValueAndVReg>
C;
539 if (
C->Value.isAllOnes())
543 return {{[=](MachineInstrBuilder &MIB) {
548 uint64_t ZExtC =
C->Value.getZExtValue();
549 return {{[=](MachineInstrBuilder &MIB) { MIB.addImm(ZExtC); }}};
552 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.
getReg()); }}};
555InstructionSelector::ComplexRendererFns
556RISCVInstructionSelector::selectAddrRegImm(MachineOperand &Root)
const {
561 if (RootDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX) {
563 [=](MachineInstrBuilder &MIB) { MIB.add(RootDef->
getOperand(1)); },
564 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
568 if (isBaseWithConstantOffset(Root, *MRI)) {
576 if (LHSDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX)
578 [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->
getOperand(1)); },
579 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
582 return {{[=](MachineInstrBuilder &MIB) { MIB.add(
LHS); },
583 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }}};
589 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.
getReg()); },
590 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
599 case CmpInst::Predicate::ICMP_EQ:
601 case CmpInst::Predicate::ICMP_NE:
603 case CmpInst::Predicate::ICMP_ULT:
605 case CmpInst::Predicate::ICMP_SLT:
607 case CmpInst::Predicate::ICMP_UGE:
609 case CmpInst::Predicate::ICMP_SGE:
675 CC = getRISCVCCFromICmp(Pred);
682 const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
687 return IsStore ? RISCV::SB_RL : RISCV::LB_AQ;
689 return IsStore ? RISCV::SH_RL : RISCV::LH_AQ;
691 return IsStore ? RISCV::SW_RL : RISCV::LW_AQ;
693 return IsStore ? RISCV::SD_RL : RISCV::LD_AQ;
701 const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
705 return IsStore ? RISCV::SB : RISCV::LBU;
707 return IsStore ? RISCV::SH : RISCV::LH;
709 return IsStore ? RISCV::SW : RISCV::LW;
711 return IsStore ? RISCV::SD : RISCV::LD;
717void RISCVInstructionSelector::addVectorLoadStoreOperands(
718 MachineInstr &
I, SmallVectorImpl<Register> &SrcOps,
unsigned &CurOp,
719 bool IsMasked,
bool IsStridedOrIndexed, LLT *IndexVT)
const {
721 auto PtrReg =
I.getOperand(CurOp++).getReg();
725 if (IsStridedOrIndexed) {
726 auto StrideReg =
I.getOperand(CurOp++).getReg();
729 *IndexVT = MRI->
getType(StrideReg);
734 auto MaskReg =
I.getOperand(CurOp++).getReg();
739bool RISCVInstructionSelector::selectIntrinsicWithSideEffects(
740 MachineInstr &
I)
const {
747 case Intrinsic::riscv_vlm:
748 case Intrinsic::riscv_vle:
749 case Intrinsic::riscv_vle_mask:
750 case Intrinsic::riscv_vlse:
751 case Intrinsic::riscv_vlse_mask: {
752 bool IsMasked = IntrinID == Intrinsic::riscv_vle_mask ||
753 IntrinID == Intrinsic::riscv_vlse_mask;
754 bool IsStrided = IntrinID == Intrinsic::riscv_vlse ||
755 IntrinID == Intrinsic::riscv_vlse_mask;
756 LLT VT = MRI->
getType(
I.getOperand(0).getReg());
760 const Register DstReg =
I.getOperand(0).getReg();
763 bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
768 if (HasPassthruOperand) {
769 auto PassthruReg =
I.getOperand(CurOp++).getReg();
775 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked, IsStrided);
778 const RISCV::VLEPseudo *
P =
779 RISCV::getVLEPseudo(IsMasked, IsStrided,
false, Log2SEW,
780 static_cast<unsigned>(LMUL));
782 MachineInstrBuilder PseudoMI =
783 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(
P->Pseudo), DstReg);
788 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
789 for (
auto &RenderFn : *VLOpFn)
798 Policy =
I.getOperand(CurOp++).getImm();
808 case Intrinsic::riscv_vloxei:
809 case Intrinsic::riscv_vloxei_mask:
810 case Intrinsic::riscv_vluxei:
811 case Intrinsic::riscv_vluxei_mask: {
812 bool IsMasked = IntrinID == Intrinsic::riscv_vloxei_mask ||
813 IntrinID == Intrinsic::riscv_vluxei_mask;
814 bool IsOrdered = IntrinID == Intrinsic::riscv_vloxei ||
815 IntrinID == Intrinsic::riscv_vloxei_mask;
816 LLT VT = MRI->
getType(
I.getOperand(0).getReg());
820 const Register DstReg =
I.getOperand(0).getReg();
823 bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
828 if (HasPassthruOperand) {
829 auto PassthruReg =
I.getOperand(CurOp++).getReg();
836 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked,
true, &IndexVT);
842 if (IndexLog2EEW == 6 && !Subtarget->
is64Bit()) {
844 "values when XLEN=32");
846 const RISCV::VLX_VSXPseudo *
P = RISCV::getVLXPseudo(
847 IsMasked, IsOrdered, IndexLog2EEW,
static_cast<unsigned>(LMUL),
848 static_cast<unsigned>(IndexLMUL));
850 MachineInstrBuilder PseudoMI =
851 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(
P->Pseudo), DstReg);
856 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
857 for (
auto &RenderFn : *VLOpFn)
866 Policy =
I.getOperand(CurOp++).getImm();
876 case Intrinsic::riscv_vsm:
877 case Intrinsic::riscv_vse:
878 case Intrinsic::riscv_vse_mask:
879 case Intrinsic::riscv_vsse:
880 case Intrinsic::riscv_vsse_mask: {
881 bool IsMasked = IntrinID == Intrinsic::riscv_vse_mask ||
882 IntrinID == Intrinsic::riscv_vsse_mask;
883 bool IsStrided = IntrinID == Intrinsic::riscv_vsse ||
884 IntrinID == Intrinsic::riscv_vsse_mask;
885 LLT VT = MRI->
getType(
I.getOperand(1).getReg());
893 auto PassthruReg =
I.getOperand(CurOp++).getReg();
896 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked, IsStrided);
899 const RISCV::VSEPseudo *
P = RISCV::getVSEPseudo(
900 IsMasked, IsStrided, Log2SEW,
static_cast<unsigned>(LMUL));
902 MachineInstrBuilder PseudoMI =
908 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
909 for (
auto &RenderFn : *VLOpFn)
922 case Intrinsic::riscv_vsoxei:
923 case Intrinsic::riscv_vsoxei_mask:
924 case Intrinsic::riscv_vsuxei:
925 case Intrinsic::riscv_vsuxei_mask: {
926 bool IsMasked = IntrinID == Intrinsic::riscv_vsoxei_mask ||
927 IntrinID == Intrinsic::riscv_vsuxei_mask;
928 bool IsOrdered = IntrinID == Intrinsic::riscv_vsoxei ||
929 IntrinID == Intrinsic::riscv_vsoxei_mask;
930 LLT VT = MRI->
getType(
I.getOperand(1).getReg());
938 auto PassthruReg =
I.getOperand(CurOp++).getReg();
942 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked,
true, &IndexVT);
948 if (IndexLog2EEW == 6 && !Subtarget->
is64Bit()) {
950 "values when XLEN=32");
952 const RISCV::VLX_VSXPseudo *
P = RISCV::getVSXPseudo(
953 IsMasked, IsOrdered, IndexLog2EEW,
static_cast<unsigned>(LMUL),
954 static_cast<unsigned>(IndexLMUL));
956 MachineInstrBuilder PseudoMI =
962 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
963 for (
auto &RenderFn : *VLOpFn)
979bool RISCVInstructionSelector::selectIntrinsic(MachineInstr &
I)
const {
986 case Intrinsic::riscv_vsetvli:
987 case Intrinsic::riscv_vsetvlimax: {
989 bool VLMax = IntrinID == Intrinsic::riscv_vsetvlimax;
991 unsigned Offset = VLMax ? 2 : 3;
999 Register DstReg =
I.getOperand(0).getReg();
1002 unsigned Opcode = RISCV::PseudoVSETVLI;
1006 Register AVLReg =
I.getOperand(2).getReg();
1008 uint64_t AVL = AVLConst->Value.getZExtValue();
1021 Opcode = RISCV::PseudoVSETVLIX0;
1023 Register AVLReg =
I.getOperand(2).getReg();
1028 uint64_t AVL = AVLConst->Value.getZExtValue();
1030 MachineInstr *PseudoMI =
1032 TII.get(RISCV::PseudoVSETIVLI), DstReg)
1035 I.eraseFromParent();
1042 MachineInstr *PseudoMI =
1043 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode), DstReg)
1046 I.eraseFromParent();
1053bool RISCVInstructionSelector::selectExtractSubvector(MachineInstr &
MI)
const {
1054 assert(
MI.getOpcode() == TargetOpcode::G_EXTRACT_SUBVECTOR);
1059 LLT DstTy = MRI->
getType(DstReg);
1060 LLT SrcTy = MRI->
getType(SrcReg);
1062 unsigned Idx =
static_cast<unsigned>(
MI.getOperand(2).
getImm());
1068 std::tie(SubRegIdx, Idx) =
1070 SrcMVT, DstMVT, Idx, &
TRI);
1085 BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1087 .
addReg(SrcReg, {}, SubRegIdx);
1089 MI.eraseFromParent();
1093bool RISCVInstructionSelector::selectInsertSubVector(MachineInstr &
MI)
const {
1094 assert(
MI.getOpcode() == TargetOpcode::G_INSERT_SUBVECTOR);
1098 Register SubVecReg =
MI.getOperand(2).getReg();
1100 LLT VecTy = MRI->
getType(VecReg);
1101 LLT SubVecTy = MRI->
getType(SubVecReg);
1106 unsigned Idx =
static_cast<unsigned>(
MI.getOperand(3).
getImm());
1109 std::tie(SubRegIdx, Idx) =
1111 VecMVT, SubVecMVT, Idx, &
TRI);
1127 if (SubRegIdx == RISCV::NoSubRegister) {
1130 "Unexpected subvector insert");
1131 BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1134 MI.eraseFromParent();
1140 MachineInstr *Ins =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1141 TII.get(TargetOpcode::INSERT_SUBREG), DstReg)
1146 MI.eraseFromParent();
1151bool RISCVInstructionSelector::select(MachineInstr &
MI) {
1153 const unsigned Opc =
MI.getOpcode();
1155 if (!
MI.isPreISelOpcode() ||
Opc == TargetOpcode::G_PHI) {
1156 if (
Opc == TargetOpcode::PHI ||
Opc == TargetOpcode::G_PHI) {
1157 const Register DefReg =
MI.getOperand(0).getReg();
1158 const LLT DefTy = MRI->
getType(DefReg);
1172 DefRC =
TRI.getRegClassForTypeOnBank(DefTy, RB, STI.
is64Bit());
1179 MI.setDesc(
TII.get(TargetOpcode::PHI));
1190 if (selectImpl(
MI, *CoverageInfo))
1194 case TargetOpcode::G_ANYEXT:
1195 case TargetOpcode::G_PTRTOINT:
1196 case TargetOpcode::G_INTTOPTR:
1197 case TargetOpcode::G_TRUNC:
1198 case TargetOpcode::G_FREEZE:
1200 case TargetOpcode::G_CONSTANT: {
1202 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
1204 if (!materializeImm(DstReg,
Imm,
MI))
1207 MI.eraseFromParent();
1210 case TargetOpcode::G_ZEXT:
1211 case TargetOpcode::G_SEXT: {
1212 bool IsSigned =
Opc != TargetOpcode::G_ZEXT;
1215 LLT SrcTy = MRI->
getType(SrcReg);
1222 RISCV::GPRBRegBankID &&
1223 "Unexpected ext regbank");
1226 if (IsSigned && SrcSize == 32) {
1227 MI.setDesc(
TII.get(RISCV::ADDIW));
1234 if (!IsSigned && SrcSize == 32 && STI.hasStdExtZba()) {
1235 MI.setDesc(
TII.get(RISCV::ADD_UW));
1242 if (SrcSize == 16 &&
1243 (STI.hasStdExtZbb() || (!IsSigned && STI.hasStdExtZbkb()))) {
1244 MI.setDesc(
TII.get(IsSigned ? RISCV::SEXT_H
1245 : STI.isRV64() ? RISCV::ZEXT_H_RV64
1246 : RISCV::ZEXT_H_RV32));
1253 MachineInstr *ShiftLeft =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1254 TII.get(RISCV::SLLI), ShiftLeftReg)
1258 MachineInstr *ShiftRight =
1260 TII.get(IsSigned ? RISCV::SRAI : RISCV::SRLI), DstReg)
1264 MI.eraseFromParent();
1267 case TargetOpcode::G_FCONSTANT: {
1270 const APFloat &FPimm =
MI.getOperand(1).getFPImm()->getValueAPF();
1279 if (!materializeImm(GPRReg,
Imm.getSExtValue(),
MI))
1283 unsigned Opcode =
Size == 64 ? RISCV::FMV_D_X
1284 :
Size == 32 ? RISCV::FMV_W_X
1286 MachineInstr *FMV =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1287 TII.get(Opcode), DstReg)
1293 "Unexpected size or subtarget");
1297 MachineInstr *FCVT =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1298 TII.get(RISCV::FCVT_D_W), DstReg)
1303 MI.eraseFromParent();
1311 if (!materializeImm(GPRRegHigh,
Imm.extractBits(32, 32).getSExtValue(),
1314 if (!materializeImm(GPRRegLow,
Imm.trunc(32).getSExtValue(),
MI))
1316 MachineInstr *PairF64 =
1318 TII.get(RISCV::BuildPairF64Pseudo), DstReg)
1324 MI.eraseFromParent();
1327 case TargetOpcode::G_GLOBAL_VALUE: {
1328 auto *GV =
MI.getOperand(1).getGlobal();
1329 if (GV->isThreadLocal()) {
1334 return selectAddr(
MI, GV->isDSOLocal(), GV->hasExternalWeakLinkage());
1336 case TargetOpcode::G_JUMP_TABLE:
1337 case TargetOpcode::G_CONSTANT_POOL:
1338 return selectAddr(
MI);
1339 case TargetOpcode::G_BRCOND: {
1344 MachineInstr *Bcc =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1348 .
addMBB(
MI.getOperand(1).getMBB());
1349 MI.eraseFromParent();
1353 case TargetOpcode::G_BRINDIRECT:
1354 MI.setDesc(
TII.get(RISCV::PseudoBRIND));
1358 case TargetOpcode::G_SELECT:
1359 return selectSelect(
MI);
1360 case TargetOpcode::G_FCMP:
1361 return selectFPCompare(
MI);
1362 case TargetOpcode::G_FENCE: {
1367 emitFence(FenceOrdering, FenceSSID,
MI);
1368 MI.eraseFromParent();
1371 case TargetOpcode::G_IMPLICIT_DEF:
1372 return selectImplicitDef(
MI);
1373 case TargetOpcode::G_UNMERGE_VALUES:
1375 case TargetOpcode::G_LOAD:
1376 case TargetOpcode::G_STORE: {
1380 LLT PtrTy = MRI->
getType(PtrReg);
1382 const RegisterBank &RB = *RBI.
getRegBank(ValReg, *MRI,
TRI);
1383 if (RB.
getID() != RISCV::GPRBRegBankID)
1387 const RegisterBank &PtrRB = *RBI.
getRegBank(PtrReg, *MRI,
TRI);
1390 "Load/Store pointer operand isn't a GPR");
1391 assert(PtrTy.
isPointer() &&
"Load/Store pointer operand isn't a pointer");
1408 if (NewOpc ==
MI.getOpcode())
1412 auto AddrModeFns = selectAddrRegImm(
MI.getOperand(1));
1417 MachineInstrBuilder NewInst =
1425 for (
auto &Fn : *AddrModeFns)
1427 MI.eraseFromParent();
1432 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
1433 return selectIntrinsicWithSideEffects(
MI);
1434 case TargetOpcode::G_INTRINSIC:
1435 return selectIntrinsic(
MI);
1436 case TargetOpcode::G_EXTRACT_SUBVECTOR:
1437 return selectExtractSubvector(
MI);
1438 case TargetOpcode::G_INSERT_SUBVECTOR:
1439 return selectInsertSubVector(
MI);
1445bool RISCVInstructionSelector::selectUnmergeValues(MachineInstr &
MI)
const {
1446 assert(
MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
1448 if (!Subtarget->hasStdExtZfa())
1452 if (
MI.getNumOperands() != 3)
1457 if (!isRegInFprb(Src) || !isRegInGprb(
Lo) || !isRegInGprb(
Hi))
1460 MachineInstr *ExtractLo =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1461 TII.get(RISCV::FMV_X_W_FPR64),
Lo)
1465 MachineInstr *ExtractHi =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1466 TII.get(RISCV::FMVH_X_D),
Hi)
1470 MI.eraseFromParent();
1474bool RISCVInstructionSelector::replacePtrWithInt(MachineOperand &
Op) {
1479 MachineInstr &ParentMI = *
Op.getParent();
1482 MachineInstr *PtrToInt =
1484 TII.get(TargetOpcode::G_PTRTOINT), IntReg)
1487 return select(*PtrToInt);
1490void RISCVInstructionSelector::preISelLower(MachineInstr &
MI) {
1491 switch (
MI.getOpcode()) {
1492 case TargetOpcode::G_PTR_ADD: {
1496 replacePtrWithInt(
MI.getOperand(1));
1497 MI.setDesc(
TII.get(TargetOpcode::G_ADD));
1501 case TargetOpcode::G_PTRMASK: {
1504 replacePtrWithInt(
MI.getOperand(1));
1505 MI.setDesc(
TII.get(TargetOpcode::G_AND));
1512void RISCVInstructionSelector::renderNegImm(MachineInstrBuilder &MIB,
1513 const MachineInstr &
MI,
1515 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1516 "Expected G_CONSTANT");
1517 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
1521void RISCVInstructionSelector::renderImmSubFromXLen(MachineInstrBuilder &MIB,
1522 const MachineInstr &
MI,
1524 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1525 "Expected G_CONSTANT");
1526 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
1530void RISCVInstructionSelector::renderImmSubFrom32(MachineInstrBuilder &MIB,
1531 const MachineInstr &
MI,
1533 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1534 "Expected G_CONSTANT");
1535 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
1539void RISCVInstructionSelector::renderImmPlus1(MachineInstrBuilder &MIB,
1540 const MachineInstr &
MI,
1542 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1543 "Expected G_CONSTANT");
1544 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
1548void RISCVInstructionSelector::renderTrailingZeros(MachineInstrBuilder &MIB,
1549 const MachineInstr &
MI,
1551 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1552 "Expected G_CONSTANT");
1553 uint64_t C =
MI.getOperand(1).getCImm()->getZExtValue();
1557void RISCVInstructionSelector::renderXLenSubTrailingOnes(
1558 MachineInstrBuilder &MIB,
const MachineInstr &
MI,
int OpIdx)
const {
1559 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1560 "Expected G_CONSTANT");
1561 uint64_t C =
MI.getOperand(1).getCImm()->getZExtValue();
1565void RISCVInstructionSelector::renderAddiPairImmSmall(MachineInstrBuilder &MIB,
1566 const MachineInstr &
MI,
1568 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1569 "Expected G_CONSTANT");
1570 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
1571 int64_t Adj =
Imm < 0 ? -2048 : 2047;
1575void RISCVInstructionSelector::renderAddiPairImmLarge(MachineInstrBuilder &MIB,
1576 const MachineInstr &
MI,
1578 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1579 "Expected G_CONSTANT");
1580 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue() < 0 ? -2048 : 2047;
1584bool RISCVInstructionSelector::isRegInGprb(
Register Reg)
const {
1588bool RISCVInstructionSelector::isRegInFprb(
Register Reg)
const {
1592bool RISCVInstructionSelector::selectCopy(MachineInstr &
MI)
const {
1593 MachineOperand Dst =
MI.getOperand(0);
1600 TRI.getConstrainedRegClassForOperand(Dst, *MRI);
1603 "Register class not available for LLT, register bank combination");
1614 MI.setDesc(
TII.get(RISCV::COPY));
1618bool RISCVInstructionSelector::selectImplicitDef(MachineInstr &
MI)
const {
1619 assert(
MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
1621 const Register DstReg =
MI.getOperand(0).getReg();
1626 "Register class not available for LLT, register bank combination");
1632 MI.setDesc(
TII.get(TargetOpcode::IMPLICIT_DEF));
1636bool RISCVInstructionSelector::materializeImm(
Register DstReg, int64_t
Imm,
1637 MachineInstr &
MI)
const {
1648 unsigned NumInsts = Seq.
size();
1651 for (
unsigned i = 0; i < NumInsts; i++) {
1655 const RISCVMatInt::Inst &
I = Seq[i];
1658 switch (
I.getOpndKind()) {
1690bool RISCVInstructionSelector::selectAddr(MachineInstr &
MI,
bool IsLocal,
1691 bool IsExternWeak)
const {
1692 assert((
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
1693 MI.getOpcode() == TargetOpcode::G_JUMP_TABLE ||
1694 MI.getOpcode() == TargetOpcode::G_CONSTANT_POOL) &&
1695 "Unexpected opcode");
1697 const MachineOperand &DispMO =
MI.getOperand(1);
1700 const LLT DefTy = MRI->
getType(DefReg);
1707 if (IsLocal && !Subtarget->allowTaggedGlobals()) {
1711 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1728 TII.get(RISCV::PseudoLGA), DefReg)
1734 MI.eraseFromParent();
1741 "Unsupported code model for lowering",
MI);
1749 MachineInstr *AddrHi =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1750 TII.get(RISCV::LUI), AddrHiDest)
1756 TII.get(RISCV::ADDI), DefReg)
1762 MI.eraseFromParent();
1783 TII.get(RISCV::PseudoLGA), DefReg)
1789 MI.eraseFromParent();
1796 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1804bool RISCVInstructionSelector::selectSelect(MachineInstr &
MI)
const {
1811 Register DstReg = SelectMI.getReg(0);
1813 unsigned Opc = RISCV::Select_GPR_Using_CC_GPR;
1816 Opc =
Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR
1817 : RISCV::Select_FPR64_Using_CC_GPR;
1826 .
addReg(SelectMI.getTrueReg())
1827 .
addReg(SelectMI.getFalseReg());
1828 MI.eraseFromParent();
1840 return Size == 16 ? RISCV::FLT_H :
Size == 32 ? RISCV::FLT_S : RISCV::FLT_D;
1842 return Size == 16 ? RISCV::FLE_H :
Size == 32 ? RISCV::FLE_S : RISCV::FLE_D;
1844 return Size == 16 ? RISCV::FEQ_H :
Size == 32 ? RISCV::FEQ_S : RISCV::FEQ_D;
1857 assert(!isLegalFCmpPredicate(Pred) &&
"Predicate already legal?");
1860 if (isLegalFCmpPredicate(InvPred)) {
1868 if (isLegalFCmpPredicate(InvPred)) {
1873 if (isLegalFCmpPredicate(InvPred)) {
1885bool RISCVInstructionSelector::selectFPCompare(MachineInstr &
MI)
const {
1898 bool NeedInvert =
false;
1912 MachineInstr *Cmp1 =
1919 MachineInstr *Cmp2 =
1928 TII.get(RISCV::OR), TmpReg)
1947 MachineInstr *Cmp1 =
1954 MachineInstr *Cmp2 =
1961 TII.get(RISCV::AND), TmpReg)
1972 TII.get(RISCV::XORI), DstReg)
1978 MI.eraseFromParent();
1982void RISCVInstructionSelector::emitFence(
AtomicOrdering FenceOrdering,
1984 MachineInstr &
MI)
const {
1988 if (STI.hasStdExtZtso()) {
1991 if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
2015 unsigned Pred, Succ;
2016 switch (FenceOrdering) {
2019 case AtomicOrdering::AcquireRelease:
2023 case AtomicOrdering::Acquire:
2028 case AtomicOrdering::Release:
2033 case AtomicOrdering::SequentiallyConsistent:
2043InstructionSelector *
2047 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
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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
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
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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
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 LLVM_READONLY 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.
operand_type_match m_Reg()
SpecificConstantMatch m_SpecificICst(const APInt &RequestedValue)
Matches a constant equal to RequestedValue.
GCstAndRegMatch m_GCst(std::optional< ValueAndVReg > &ValReg)
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)
SpecificImmMatch m_SpecificImm(int64_t RequestedValue)
Matches an immediate operand equal to RequestedValue.
AllOnesConstantMatch m_AllOnes()
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)
SrcImmOp_match< SrcTy, AnyImmMatch, TargetOpcode::G_SEXT_INREG > m_GSExtInReg(const SrcTy &Src)
Matches a G_SEXT_INREG, binding its source and immediate width.
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.