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;
90 bool IsExternWeak =
false)
const;
98 unsigned &CurOp,
bool IsMasked,
99 bool IsStridedOrIndexed,
100 LLT *IndexVT =
nullptr)
const;
106 unsigned ShiftWidth)
const;
107 ComplexRendererFns selectShiftMaskXLen(
MachineOperand &Root)
const {
108 return selectShiftMask(Root, STI.
getXLen());
110 ComplexRendererFns selectShiftMask32(
MachineOperand &Root)
const {
111 return selectShiftMask(Root, 32);
114 ComplexRendererFns selectAddrRegImmLsb00000(
MachineOperand &Root)
const;
119 struct ConstAddrPlan {
120 enum { X0, LUI, InstSeq } Kind = X0;
125 ComplexRendererFns computeConstAddr(int64_t CVal,
bool IsPrefetch,
130 const ConstAddrPlan &Plan,
133 ComplexRendererFns selectSExtBits(
MachineOperand &Root,
unsigned Bits)
const;
134 template <
unsigned Bits>
136 return selectSExtBits(Root, Bits);
139 ComplexRendererFns selectZExtBits(
MachineOperand &Root,
unsigned Bits)
const;
140 template <
unsigned Bits>
142 return selectZExtBits(Root, Bits);
145 ComplexRendererFns selectSHXADDOp(
MachineOperand &Root,
unsigned ShAmt)
const;
146 template <
unsigned ShAmt>
148 return selectSHXADDOp(Root, ShAmt);
152 unsigned ShAmt)
const;
153 template <
unsigned ShAmt>
154 ComplexRendererFns selectSHXADD_UWOp(
MachineOperand &Root)
const {
155 return selectSHXADD_UWOp(Root, ShAmt);
159 ComplexRendererFns renderAddiPair(
Register BaseReg, int64_t AddiImm,
160 int64_t OffsetImm)
const;
194#define GET_GLOBALISEL_PREDICATES_DECL
195#include "RISCVGenGlobalISel.inc"
196#undef GET_GLOBALISEL_PREDICATES_DECL
198#define GET_GLOBALISEL_TEMPORARIES_DECL
199#include "RISCVGenGlobalISel.inc"
200#undef GET_GLOBALISEL_TEMPORARIES_DECL
205#define GET_GLOBALISEL_IMPL
206#include "RISCVGenGlobalISel.inc"
207#undef GET_GLOBALISEL_IMPL
209RISCVInstructionSelector::RISCVInstructionSelector(
212 : STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()), RBI(RBI),
216#include
"RISCVGenGlobalISel.inc"
219#include
"RISCVGenGlobalISel.inc"
225bool RISCVInstructionSelector::hasAllNBitUsers(
const MachineInstr &
MI,
227 const unsigned Depth)
const {
229 assert((
MI.getOpcode() == TargetOpcode::G_ADD ||
230 MI.getOpcode() == TargetOpcode::G_SUB ||
231 MI.getOpcode() == TargetOpcode::G_MUL ||
232 MI.getOpcode() == TargetOpcode::G_SHL ||
233 MI.getOpcode() == TargetOpcode::G_LSHR ||
234 MI.getOpcode() == TargetOpcode::G_AND ||
235 MI.getOpcode() == TargetOpcode::G_OR ||
236 MI.getOpcode() == TargetOpcode::G_XOR ||
237 MI.getOpcode() == TargetOpcode::G_SEXT_INREG ||
Depth != 0) &&
238 "Unexpected opcode");
240 if (
Depth >= RISCVInstructionSelector::MaxRecursionDepth)
243 auto DestReg =
MI.getOperand(0).getReg();
245 assert(UserOp.getParent() &&
"UserOp must have a parent");
246 const MachineInstr &UserMI = *UserOp.getParent();
247 unsigned OpIdx = UserOp.getOperandNo();
255 case RISCV::FCVT_D_W:
256 case RISCV::FCVT_S_W:
299InstructionSelector::ComplexRendererFns
300RISCVInstructionSelector::selectShiftMask(MachineOperand &Root,
301 unsigned ShiftWidth)
const {
305 using namespace llvm::MIPatternMatch;
311 ShAmtReg = ZExtSrcReg;
330 APInt ShMask(AndMask.
getBitWidth(), ShiftWidth - 1);
331 if (ShMask.isSubsetOf(AndMask)) {
332 ShAmtReg = AndSrcReg;
336 KnownBits
Known = VT->getKnownBits(AndSrcReg);
337 if (ShMask.isSubsetOf(AndMask |
Known.Zero))
338 ShAmtReg = AndSrcReg;
345 if (
Imm != 0 &&
Imm.urem(ShiftWidth) == 0)
350 if (
Imm != 0 &&
Imm.urem(ShiftWidth) == 0) {
354 unsigned NegOpc = Subtarget->
is64Bit() ? RISCV::SUBW : RISCV::SUB;
355 return {{[=](MachineInstrBuilder &MIB) {
356 MachineIRBuilder(*MIB.getInstr())
357 .buildInstr(NegOpc, {ShAmtReg}, {
Register(RISCV::X0),
Reg});
358 MIB.addReg(ShAmtReg);
361 if (
Imm.urem(ShiftWidth) == ShiftWidth - 1) {
365 return {{[=](MachineInstrBuilder &MIB) {
366 MachineIRBuilder(*MIB.getInstr())
367 .buildInstr(RISCV::XORI, {ShAmtReg}, {
Reg})
369 MIB.addReg(ShAmtReg);
374 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(ShAmtReg); }}};
377InstructionSelector::ComplexRendererFns
378RISCVInstructionSelector::selectSExtBits(MachineOperand &Root,
379 unsigned Bits)
const {
387 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(SrcReg); }}};
391 if ((
Size - VT->computeNumSignBits(RootReg)) < Bits)
392 return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
397InstructionSelector::ComplexRendererFns
398RISCVInstructionSelector::selectZExtBits(MachineOperand &Root,
399 unsigned Bits)
const {
407 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}};
412 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}};
416 return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
421InstructionSelector::ComplexRendererFns
422RISCVInstructionSelector::selectSHXADDOp(MachineOperand &Root,
423 unsigned ShAmt)
const {
424 using namespace llvm::MIPatternMatch;
430 const unsigned XLen = STI.
getXLen();
449 if (
Mask.isShiftedMask()) {
450 unsigned Leading = XLen -
Mask.getActiveBits();
451 unsigned Trailing =
Mask.countr_zero();
454 if (*LeftShift && Leading == 0 && C2.
ult(Trailing) && Trailing == ShAmt) {
456 return {{[=](MachineInstrBuilder &MIB) {
457 MachineIRBuilder(*MIB.getInstr())
458 .buildInstr(RISCV::SRLI, {DstReg}, {RegY})
466 if (!*LeftShift && Leading == C2 && Trailing == ShAmt) {
468 return {{[=](MachineInstrBuilder &MIB) {
469 MachineIRBuilder(*MIB.getInstr())
470 .buildInstr(RISCV::SRLI, {DstReg}, {RegY})
471 .addImm(Leading + Trailing);
492 unsigned Leading = XLen -
Mask.getActiveBits();
493 unsigned Trailing =
Mask.countr_zero();
507 return {{[=](MachineInstrBuilder &MIB) {
508 MachineIRBuilder(*MIB.getInstr())
509 .buildInstr(RISCV::SRLIW, {DstReg}, {RegY})
519InstructionSelector::ComplexRendererFns
520RISCVInstructionSelector::selectSHXADD_UWOp(MachineOperand &Root,
521 unsigned ShAmt)
const {
522 using namespace llvm::MIPatternMatch;
539 if (
Mask.isShiftedMask()) {
540 unsigned Leading =
Mask.countl_zero();
541 unsigned Trailing =
Mask.countr_zero();
542 if (Leading == 32 - ShAmt && C2 == Trailing && Trailing > ShAmt) {
544 return {{[=](MachineInstrBuilder &MIB) {
545 MachineIRBuilder(*MIB.getInstr())
546 .buildInstr(RISCV::SLLI, {DstReg}, {RegX})
557InstructionSelector::ComplexRendererFns
558RISCVInstructionSelector::renderVLOp(MachineOperand &Root)
const {
559 assert(Root.
isReg() &&
"Expected operand to be a Register");
560 std::optional<ValueAndVReg>
C;
562 if (
C->Value.isAllOnes())
566 return {{[=](MachineInstrBuilder &MIB) {
571 uint64_t ZExtC =
C->Value.getZExtValue();
572 return {{[=](MachineInstrBuilder &MIB) { MIB.addImm(ZExtC); }}};
575 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.
getReg()); }}};
578InstructionSelector::ComplexRendererFns
579RISCVInstructionSelector::renderAddiPair(
Register BaseReg, int64_t AddiImm,
580 int64_t OffsetImm)
const {
581 return {{[=](MachineInstrBuilder &MIB) {
584 BuildMI(*MIB->getParent(), *MIB.getInstr(), MIB->getDebugLoc(),
585 TII.get(RISCV::ADDI), Tmp)
591 [=](MachineInstrBuilder &MIB) { MIB.addImm(OffsetImm); }}};
594InstructionSelector::ComplexRendererFns
595RISCVInstructionSelector::selectAddrRegImm(MachineOperand &Root)
const {
605 [=](MachineInstrBuilder &MIB) { MIB.addFrameIndex(FI); },
606 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
618 [=](MachineInstrBuilder &MIB) { MIB.addFrameIndex(BaseFI); },
619 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
622 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(BaseReg); },
623 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }}};
628 if (RHSC >= -4096 && RHSC <= 4094) {
629 int64_t Adj = RHSC < 0 ? -2048 : 2047;
630 return renderAddiPair(BaseReg, Adj, RHSC - Adj);
634 if (
auto Fns = computeConstAddr(RHSC,
false, BaseReg))
643 if (
auto Fns = computeConstAddr(CVal,
false,
Register()))
647 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RootReg); },
648 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
651InstructionSelector::ComplexRendererFns
652RISCVInstructionSelector::selectAddrRegImmLsb00000(MachineOperand &Root)
const {
662 [=](MachineInstrBuilder &MIB) { MIB.addFrameIndex(FI); },
663 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
673 if ((RHSC & 0b11111) != 0) {
674 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RootReg); },
675 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
681 [=](MachineInstrBuilder &MIB) { MIB.addFrameIndex(BaseFI); },
682 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
684 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(BaseReg); },
685 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }}};
689 if ((-2049 >= RHSC && RHSC >= -4096) || (4063 >= RHSC && RHSC >= 2017)) {
690 int64_t Adj = RHSC < 0 ? -2048 : 2016;
691 return renderAddiPair(BaseReg, RHSC - Adj, Adj);
696 if (
auto Fns = computeConstAddr(RHSC,
true, BaseReg))
705 if (
auto Fns = computeConstAddr(CVal,
true,
Register()))
709 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RootReg); },
710 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
719 case CmpInst::Predicate::ICMP_EQ:
721 case CmpInst::Predicate::ICMP_NE:
723 case CmpInst::Predicate::ICMP_ULT:
725 case CmpInst::Predicate::ICMP_SLT:
727 case CmpInst::Predicate::ICMP_UGE:
729 case CmpInst::Predicate::ICMP_SGE:
795 CC = getRISCVCCFromICmp(Pred);
802 const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
807 return IsStore ? RISCV::SB_RL : RISCV::LB_AQ;
809 return IsStore ? RISCV::SH_RL : RISCV::LH_AQ;
811 return IsStore ? RISCV::SW_RL : RISCV::LW_AQ;
813 return IsStore ? RISCV::SD_RL : RISCV::LD_AQ;
821 const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
825 return IsStore ? RISCV::SB : RISCV::LBU;
827 return IsStore ? RISCV::SH : RISCV::LH;
829 return IsStore ? RISCV::SW : RISCV::LW;
831 return IsStore ? RISCV::SD : RISCV::LD;
837void RISCVInstructionSelector::addVectorLoadStoreOperands(
838 MachineInstr &
I, SmallVectorImpl<Register> &SrcOps,
unsigned &CurOp,
839 bool IsMasked,
bool IsStridedOrIndexed, LLT *IndexVT)
const {
841 auto PtrReg =
I.getOperand(CurOp++).getReg();
845 if (IsStridedOrIndexed) {
846 auto StrideReg =
I.getOperand(CurOp++).getReg();
849 *IndexVT = MRI->
getType(StrideReg);
854 auto MaskReg =
I.getOperand(CurOp++).getReg();
859bool RISCVInstructionSelector::selectIntrinsicWithSideEffects(
860 MachineInstr &
I)
const {
867 case Intrinsic::riscv_vlm:
868 case Intrinsic::riscv_vle:
869 case Intrinsic::riscv_vle_mask:
870 case Intrinsic::riscv_vlse:
871 case Intrinsic::riscv_vlse_mask: {
872 bool IsMasked = IntrinID == Intrinsic::riscv_vle_mask ||
873 IntrinID == Intrinsic::riscv_vlse_mask;
874 bool IsStrided = IntrinID == Intrinsic::riscv_vlse ||
875 IntrinID == Intrinsic::riscv_vlse_mask;
876 LLT VT = MRI->
getType(
I.getOperand(0).getReg());
880 const Register DstReg =
I.getOperand(0).getReg();
883 bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
888 if (HasPassthruOperand) {
889 auto PassthruReg =
I.getOperand(CurOp++).getReg();
895 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked, IsStrided);
898 const RISCV::VLEPseudo *
P =
899 RISCV::getVLEPseudo(IsMasked, IsStrided,
false, Log2SEW,
900 static_cast<unsigned>(LMUL));
902 MachineInstrBuilder PseudoMI =
903 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(
P->Pseudo), DstReg);
908 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
909 for (
auto &RenderFn : *VLOpFn)
918 Policy =
I.getOperand(CurOp++).getImm();
928 case Intrinsic::riscv_vloxei:
929 case Intrinsic::riscv_vloxei_mask:
930 case Intrinsic::riscv_vluxei:
931 case Intrinsic::riscv_vluxei_mask: {
932 bool IsMasked = IntrinID == Intrinsic::riscv_vloxei_mask ||
933 IntrinID == Intrinsic::riscv_vluxei_mask;
934 bool IsOrdered = IntrinID == Intrinsic::riscv_vloxei ||
935 IntrinID == Intrinsic::riscv_vloxei_mask;
936 LLT VT = MRI->
getType(
I.getOperand(0).getReg());
940 const Register DstReg =
I.getOperand(0).getReg();
943 bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
948 if (HasPassthruOperand) {
949 auto PassthruReg =
I.getOperand(CurOp++).getReg();
956 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked,
true, &IndexVT);
962 if (IndexLog2EEW == 6 && !Subtarget->
is64Bit()) {
964 "values when XLEN=32");
966 const RISCV::VLX_VSXPseudo *
P = RISCV::getVLXPseudo(
967 IsMasked, IsOrdered, IndexLog2EEW,
static_cast<unsigned>(LMUL),
968 static_cast<unsigned>(IndexLMUL));
970 MachineInstrBuilder PseudoMI =
971 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(
P->Pseudo), DstReg);
976 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
977 for (
auto &RenderFn : *VLOpFn)
986 Policy =
I.getOperand(CurOp++).getImm();
996 case Intrinsic::riscv_vsm:
997 case Intrinsic::riscv_vse:
998 case Intrinsic::riscv_vse_mask:
999 case Intrinsic::riscv_vsse:
1000 case Intrinsic::riscv_vsse_mask: {
1001 bool IsMasked = IntrinID == Intrinsic::riscv_vse_mask ||
1002 IntrinID == Intrinsic::riscv_vsse_mask;
1003 bool IsStrided = IntrinID == Intrinsic::riscv_vsse ||
1004 IntrinID == Intrinsic::riscv_vsse_mask;
1005 LLT VT = MRI->
getType(
I.getOperand(1).getReg());
1013 auto PassthruReg =
I.getOperand(CurOp++).getReg();
1016 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked, IsStrided);
1019 const RISCV::VSEPseudo *
P = RISCV::getVSEPseudo(
1020 IsMasked, IsStrided, Log2SEW,
static_cast<unsigned>(LMUL));
1022 MachineInstrBuilder PseudoMI =
1028 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
1029 for (
auto &RenderFn : *VLOpFn)
1033 PseudoMI.
addImm(Log2SEW);
1038 I.eraseFromParent();
1042 case Intrinsic::riscv_vsoxei:
1043 case Intrinsic::riscv_vsoxei_mask:
1044 case Intrinsic::riscv_vsuxei:
1045 case Intrinsic::riscv_vsuxei_mask: {
1046 bool IsMasked = IntrinID == Intrinsic::riscv_vsoxei_mask ||
1047 IntrinID == Intrinsic::riscv_vsuxei_mask;
1048 bool IsOrdered = IntrinID == Intrinsic::riscv_vsoxei ||
1049 IntrinID == Intrinsic::riscv_vsoxei_mask;
1050 LLT VT = MRI->
getType(
I.getOperand(1).getReg());
1058 auto PassthruReg =
I.getOperand(CurOp++).getReg();
1062 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked,
true, &IndexVT);
1068 if (IndexLog2EEW == 6 && !Subtarget->
is64Bit()) {
1070 "values when XLEN=32");
1072 const RISCV::VLX_VSXPseudo *
P = RISCV::getVSXPseudo(
1073 IsMasked, IsOrdered, IndexLog2EEW,
static_cast<unsigned>(LMUL),
1074 static_cast<unsigned>(IndexLMUL));
1076 MachineInstrBuilder PseudoMI =
1082 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
1083 for (
auto &RenderFn : *VLOpFn)
1087 PseudoMI.
addImm(Log2SEW);
1092 I.eraseFromParent();
1099bool RISCVInstructionSelector::selectIntrinsic(MachineInstr &
I)
const {
1106 case Intrinsic::riscv_vsetvli:
1107 case Intrinsic::riscv_vsetvlimax: {
1109 bool VLMax = IntrinID == Intrinsic::riscv_vsetvlimax;
1111 unsigned Offset = VLMax ? 2 : 3;
1119 Register DstReg =
I.getOperand(0).getReg();
1122 unsigned Opcode = RISCV::PseudoVSETVLI;
1126 Register AVLReg =
I.getOperand(2).getReg();
1128 uint64_t AVL = AVLConst->Value.getZExtValue();
1141 Opcode = RISCV::PseudoVSETVLIX0;
1143 Register AVLReg =
I.getOperand(2).getReg();
1148 uint64_t AVL = AVLConst->Value.getZExtValue();
1150 MachineInstr *PseudoMI =
1152 TII.get(RISCV::PseudoVSETIVLI), DstReg)
1155 I.eraseFromParent();
1162 MachineInstr *PseudoMI =
1163 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode), DstReg)
1166 I.eraseFromParent();
1173bool RISCVInstructionSelector::selectExtractSubvector(MachineInstr &
MI)
const {
1174 assert(
MI.getOpcode() == TargetOpcode::G_EXTRACT_SUBVECTOR);
1179 LLT DstTy = MRI->
getType(DstReg);
1180 LLT SrcTy = MRI->
getType(SrcReg);
1182 unsigned Idx =
static_cast<unsigned>(
MI.getOperand(2).
getImm());
1188 std::tie(SubRegIdx, Idx) =
1190 SrcMVT, DstMVT, Idx, &
TRI);
1205 BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1207 .
addReg(SrcReg, {}, SubRegIdx);
1209 MI.eraseFromParent();
1213bool RISCVInstructionSelector::selectInsertSubVector(MachineInstr &
MI)
const {
1214 assert(
MI.getOpcode() == TargetOpcode::G_INSERT_SUBVECTOR);
1218 Register SubVecReg =
MI.getOperand(2).getReg();
1220 LLT VecTy = MRI->
getType(VecReg);
1221 LLT SubVecTy = MRI->
getType(SubVecReg);
1226 unsigned Idx =
static_cast<unsigned>(
MI.getOperand(3).
getImm());
1229 std::tie(SubRegIdx, Idx) =
1231 VecMVT, SubVecMVT, Idx, &
TRI);
1247 if (SubRegIdx == RISCV::NoSubRegister) {
1250 "Unexpected subvector insert");
1251 BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1254 MI.eraseFromParent();
1260 MachineInstr *Ins =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1261 TII.get(TargetOpcode::INSERT_SUBREG), DstReg)
1266 MI.eraseFromParent();
1271bool RISCVInstructionSelector::select(MachineInstr &
MI) {
1273 const unsigned Opc =
MI.getOpcode();
1275 if (!
MI.isPreISelOpcode() ||
Opc == TargetOpcode::G_PHI) {
1276 if (
Opc == TargetOpcode::PHI ||
Opc == TargetOpcode::G_PHI) {
1277 const Register DefReg =
MI.getOperand(0).getReg();
1278 const LLT DefTy = MRI->
getType(DefReg);
1292 DefRC =
TRI.getRegClassForTypeOnBank(DefTy, RB, STI.
is64Bit());
1299 MI.setDesc(
TII.get(TargetOpcode::PHI));
1310 if (selectImpl(
MI, *CoverageInfo))
1314 case TargetOpcode::G_ANYEXT:
1315 case TargetOpcode::G_PTRTOINT:
1316 case TargetOpcode::G_INTTOPTR:
1317 case TargetOpcode::G_TRUNC:
1318 case TargetOpcode::G_FREEZE:
1320 case TargetOpcode::G_CONSTANT: {
1322 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
1324 if (!materializeImm(DstReg,
Imm,
MI))
1327 MI.eraseFromParent();
1330 case TargetOpcode::G_ZEXT:
1331 case TargetOpcode::G_SEXT: {
1332 bool IsSigned =
Opc != TargetOpcode::G_ZEXT;
1335 LLT SrcTy = MRI->
getType(SrcReg);
1342 RISCV::GPRBRegBankID &&
1343 "Unexpected ext regbank");
1346 if (IsSigned && SrcSize == 32) {
1347 MI.setDesc(
TII.get(RISCV::ADDIW));
1354 if (!IsSigned && SrcSize == 32 && STI.hasStdExtZba()) {
1355 MI.setDesc(
TII.get(RISCV::ADD_UW));
1362 if (SrcSize == 16 &&
1363 (STI.hasStdExtZbb() || (!IsSigned && STI.hasStdExtZbkb()))) {
1364 MI.setDesc(
TII.get(IsSigned ? RISCV::SEXT_H
1365 : STI.isRV64() ? RISCV::ZEXT_H_RV64
1366 : RISCV::ZEXT_H_RV32));
1373 MachineInstr *ShiftLeft =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1374 TII.get(RISCV::SLLI), ShiftLeftReg)
1378 MachineInstr *ShiftRight =
1380 TII.get(IsSigned ? RISCV::SRAI : RISCV::SRLI), DstReg)
1384 MI.eraseFromParent();
1387 case TargetOpcode::G_FCONSTANT: {
1390 const APFloat &FPimm =
MI.getOperand(1).getFPImm()->getValueAPF();
1399 if (!materializeImm(GPRReg,
Imm.getSExtValue(),
MI))
1403 unsigned Opcode =
Size == 64 ? RISCV::FMV_D_X
1404 :
Size == 32 ? RISCV::FMV_W_X
1406 MachineInstr *FMV =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1407 TII.get(Opcode), DstReg)
1413 "Unexpected size or subtarget");
1417 MachineInstr *FCVT =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1418 TII.get(RISCV::FCVT_D_W), DstReg)
1423 MI.eraseFromParent();
1431 if (!materializeImm(GPRRegHigh,
Imm.extractBits(32, 32).getSExtValue(),
1434 if (!materializeImm(GPRRegLow,
Imm.trunc(32).getSExtValue(),
MI))
1436 MachineInstr *PairF64 =
1438 TII.get(RISCV::BuildPairF64Pseudo), DstReg)
1444 MI.eraseFromParent();
1447 case TargetOpcode::G_GLOBAL_VALUE: {
1448 auto *GV =
MI.getOperand(1).getGlobal();
1449 if (GV->isThreadLocal()) {
1454 return selectAddr(
MI, GV->isDSOLocal(), GV->hasExternalWeakLinkage());
1456 case TargetOpcode::G_JUMP_TABLE:
1457 case TargetOpcode::G_CONSTANT_POOL:
1458 return selectAddr(
MI);
1459 case TargetOpcode::G_BRCOND: {
1464 MachineInstr *Bcc =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1468 .
addMBB(
MI.getOperand(1).getMBB());
1469 MI.eraseFromParent();
1473 case TargetOpcode::G_BRINDIRECT:
1474 MI.setDesc(
TII.get(RISCV::PseudoBRIND));
1478 case TargetOpcode::G_SELECT:
1479 return selectSelect(
MI);
1480 case TargetOpcode::G_FCMP:
1481 return selectFPCompare(
MI);
1482 case TargetOpcode::G_FENCE: {
1487 emitFence(FenceOrdering, FenceSSID,
MI);
1488 MI.eraseFromParent();
1491 case TargetOpcode::G_IMPLICIT_DEF:
1492 return selectImplicitDef(
MI);
1493 case TargetOpcode::G_UNMERGE_VALUES:
1495 case TargetOpcode::G_LOAD:
1496 case TargetOpcode::G_STORE: {
1500 LLT PtrTy = MRI->
getType(PtrReg);
1502 const RegisterBank &RB = *RBI.
getRegBank(ValReg, *MRI,
TRI);
1503 if (RB.
getID() != RISCV::GPRBRegBankID)
1507 const RegisterBank &PtrRB = *RBI.
getRegBank(PtrReg, *MRI,
TRI);
1510 "Load/Store pointer operand isn't a GPR");
1511 assert(PtrTy.
isPointer() &&
"Load/Store pointer operand isn't a pointer");
1528 if (NewOpc ==
MI.getOpcode())
1532 auto AddrModeFns = selectAddrRegImm(
MI.getOperand(1));
1537 MachineInstrBuilder NewInst =
1545 for (
auto &Fn : *AddrModeFns)
1547 MI.eraseFromParent();
1552 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
1553 return selectIntrinsicWithSideEffects(
MI);
1554 case TargetOpcode::G_INTRINSIC:
1555 return selectIntrinsic(
MI);
1556 case TargetOpcode::G_EXTRACT_SUBVECTOR:
1557 return selectExtractSubvector(
MI);
1558 case TargetOpcode::G_INSERT_SUBVECTOR:
1559 return selectInsertSubVector(
MI);
1565bool RISCVInstructionSelector::selectUnmergeValues(MachineInstr &
MI)
const {
1566 assert(
MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
1568 if (!Subtarget->hasStdExtZfa())
1572 if (
MI.getNumOperands() != 3)
1577 if (!isRegInFprb(Src) || !isRegInGprb(
Lo) || !isRegInGprb(
Hi))
1580 MachineInstr *ExtractLo =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1581 TII.get(RISCV::FMV_X_W_FPR64),
Lo)
1585 MachineInstr *ExtractHi =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1586 TII.get(RISCV::FMVH_X_D),
Hi)
1590 MI.eraseFromParent();
1594bool RISCVInstructionSelector::replacePtrWithInt(MachineInstr &
MI,
1596 MachineOperand &
Op =
MI.getOperand(OpIdx);
1603 MachineInstr *PtrToInt =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1604 TII.get(TargetOpcode::G_PTRTOINT), IntReg)
1607 return select(*PtrToInt);
1610void RISCVInstructionSelector::preISelLower(MachineInstr &
MI) {
1611 switch (
MI.getOpcode()) {
1612 case TargetOpcode::G_PTR_ADD: {
1616 replacePtrWithInt(
MI, 1);
1617 MI.setDesc(
TII.get(TargetOpcode::G_ADD));
1621 case TargetOpcode::G_PTRMASK: {
1624 replacePtrWithInt(
MI, 1);
1625 MI.setDesc(
TII.get(TargetOpcode::G_AND));
1632void RISCVInstructionSelector::renderNegImm(MachineInstrBuilder &MIB,
1633 const MachineInstr &
MI,
1635 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1636 "Expected G_CONSTANT");
1637 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
1641void RISCVInstructionSelector::renderImmSubFromXLen(MachineInstrBuilder &MIB,
1642 const MachineInstr &
MI,
1644 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1645 "Expected G_CONSTANT");
1646 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
1650void RISCVInstructionSelector::renderImmSubFrom32(MachineInstrBuilder &MIB,
1651 const MachineInstr &
MI,
1653 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1654 "Expected G_CONSTANT");
1655 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
1659void RISCVInstructionSelector::renderImmPlus1(MachineInstrBuilder &MIB,
1660 const MachineInstr &
MI,
1662 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1663 "Expected G_CONSTANT");
1664 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
1668void RISCVInstructionSelector::renderTrailingZeros(MachineInstrBuilder &MIB,
1669 const MachineInstr &
MI,
1671 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1672 "Expected G_CONSTANT");
1673 uint64_t C =
MI.getOperand(1).getCImm()->getZExtValue();
1677void RISCVInstructionSelector::renderXLenSubTrailingOnes(
1678 MachineInstrBuilder &MIB,
const MachineInstr &
MI,
int OpIdx)
const {
1679 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1680 "Expected G_CONSTANT");
1681 uint64_t C =
MI.getOperand(1).getCImm()->getZExtValue();
1685void RISCVInstructionSelector::renderAddiPairImmSmall(MachineInstrBuilder &MIB,
1686 const MachineInstr &
MI,
1688 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1689 "Expected G_CONSTANT");
1690 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
1691 int64_t Adj =
Imm < 0 ? -2048 : 2047;
1695void RISCVInstructionSelector::renderAddiPairImmLarge(MachineInstrBuilder &MIB,
1696 const MachineInstr &
MI,
1698 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1699 "Expected G_CONSTANT");
1700 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue() < 0 ? -2048 : 2047;
1704bool RISCVInstructionSelector::isRegInGprb(
Register Reg)
const {
1708bool RISCVInstructionSelector::isRegInFprb(
Register Reg)
const {
1716bool RISCVInstructionSelector::isWorthFoldingAdd(
Register AddResult)
const {
1727 LLT Ty = MRI->
getType(
User.getOperand(0).getReg());
1734bool RISCVInstructionSelector::selectCopy(MachineInstr &
MI)
const {
1741 TRI.getConstrainedRegClassForReg(DstReg, *MRI);
1744 "Register class not available for LLT, register bank combination");
1755 MI.setDesc(
TII.get(RISCV::COPY));
1759bool RISCVInstructionSelector::selectImplicitDef(MachineInstr &
MI)
const {
1760 assert(
MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
1762 const Register DstReg =
MI.getOperand(0).getReg();
1767 "Register class not available for LLT, register bank combination");
1773 MI.setDesc(
TII.get(TargetOpcode::IMPLICIT_DEF));
1777bool RISCVInstructionSelector::materializeImm(
Register DstReg, int64_t
Imm,
1778 MachineInstr &
MI)
const {
1788 return materializeInstSeq(DstReg, Seq,
MI);
1791bool RISCVInstructionSelector::materializeInstSeq(
1793 assert(!Seq.
empty() &&
"materializeInstSeq requires a non-empty sequence");
1797 unsigned NumInsts = Seq.
size();
1800 for (
unsigned i = 0; i < NumInsts; i++) {
1804 const RISCVMatInt::Inst &
I = Seq[i];
1807 switch (
I.getOpndKind()) {
1837InstructionSelector::ComplexRendererFns
1838RISCVInstructionSelector::computeConstAddr(int64_t CVal,
bool IsPrefetch,
1845 auto emit = [&](ConstAddrPlan Plan) -> ComplexRendererFns {
1846 return {{[=](MachineInstrBuilder &MIB) {
1847 MIB.
addReg(materializeConstBase(MIB, Plan, OrigBase));
1849 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Plan.Lo12); }}};
1852 if (IsPrefetch && (Lo12 & 0b11111) != 0)
1853 return std::nullopt;
1857 Plan.Kind = ConstAddrPlan::LUI;
1858 Plan.Hi20 = (
Hi >> 12) & 0xfffff;
1860 return emit(std::move(Plan));
1866 if (Seq.
back().getOpcode() != RISCV::ADDI)
1867 return std::nullopt;
1868 Lo12 = Seq.
back().getImm();
1869 if (IsPrefetch && (Lo12 & 0b11111) != 0)
1870 return std::nullopt;
1873 return std::nullopt;
1875 Plan.Kind = ConstAddrPlan::InstSeq;
1876 Plan.Seq = std::move(Seq);
1878 return emit(std::move(Plan));
1882RISCVInstructionSelector::materializeConstBase(MachineInstrBuilder &MIB,
1883 const ConstAddrPlan &Plan,
1887 MachineInstr &InsertPt = *MIB.
getInstr();
1890 switch (Plan.Kind) {
1891 case ConstAddrPlan::X0:
1893 case ConstAddrPlan::LUI: {
1895 MachineInstr *LUI =
BuildMI(
MBB, InsertPt,
DL,
TII.get(RISCV::LUI), HiReg)
1900 case ConstAddrPlan::InstSeq: {
1902 materializeInstSeq(HiReg, Plan.Seq, InsertPt);
1909 if (OrigBase.
isValid() && HiReg != RISCV::X0) {
1917 return OrigBase.
isValid() ? OrigBase : HiReg;
1920bool RISCVInstructionSelector::selectAddr(MachineInstr &
MI,
bool IsLocal,
1921 bool IsExternWeak)
const {
1922 assert((
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
1923 MI.getOpcode() == TargetOpcode::G_JUMP_TABLE ||
1924 MI.getOpcode() == TargetOpcode::G_CONSTANT_POOL) &&
1925 "Unexpected opcode");
1927 const MachineOperand &DispMO =
MI.getOperand(1);
1930 const LLT DefTy = MRI->
getType(DefReg);
1937 if (IsLocal && !Subtarget->allowTaggedGlobals()) {
1941 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1958 TII.get(RISCV::PseudoLGA), DefReg)
1964 MI.eraseFromParent();
1971 "Unsupported code model for lowering",
MI);
1979 MachineInstr *AddrHi =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1980 TII.get(RISCV::LUI), AddrHiDest)
1986 TII.get(RISCV::ADDI), DefReg)
1992 MI.eraseFromParent();
2013 TII.get(RISCV::PseudoLGA), DefReg)
2019 MI.eraseFromParent();
2026 MI.setDesc(
TII.get(RISCV::PseudoLLA));
2034bool RISCVInstructionSelector::selectSelect(MachineInstr &
MI)
const {
2041 Register DstReg = SelectMI.getReg(0);
2043 unsigned Opc = RISCV::Select_GPR_Using_CC_GPR;
2046 Opc =
Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR
2047 : RISCV::Select_FPR64_Using_CC_GPR;
2056 .
addReg(SelectMI.getTrueReg())
2057 .
addReg(SelectMI.getFalseReg());
2058 MI.eraseFromParent();
2070 return Size == 16 ? RISCV::FLT_H :
Size == 32 ? RISCV::FLT_S : RISCV::FLT_D;
2072 return Size == 16 ? RISCV::FLE_H :
Size == 32 ? RISCV::FLE_S : RISCV::FLE_D;
2074 return Size == 16 ? RISCV::FEQ_H :
Size == 32 ? RISCV::FEQ_S : RISCV::FEQ_D;
2087 assert(!isLegalFCmpPredicate(Pred) &&
"Predicate already legal?");
2090 if (isLegalFCmpPredicate(InvPred)) {
2098 if (isLegalFCmpPredicate(InvPred)) {
2103 if (isLegalFCmpPredicate(InvPred)) {
2115bool RISCVInstructionSelector::selectFPCompare(MachineInstr &
MI)
const {
2128 bool NeedInvert =
false;
2142 MachineInstr *Cmp1 =
2149 MachineInstr *Cmp2 =
2158 TII.get(RISCV::OR), TmpReg)
2177 MachineInstr *Cmp1 =
2184 MachineInstr *Cmp2 =
2191 TII.get(RISCV::AND), TmpReg)
2202 TII.get(RISCV::XORI), DstReg)
2208 MI.eraseFromParent();
2212void RISCVInstructionSelector::emitFence(
AtomicOrdering FenceOrdering,
2214 MachineInstr &
MI)
const {
2218 if (STI.hasStdExtZtso()) {
2221 if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
2245 unsigned Pred, Succ;
2246 switch (FenceOrdering) {
2249 case AtomicOrdering::AcquireRelease:
2253 case AtomicOrdering::Acquire:
2258 case AtomicOrdering::Release:
2263 case AtomicOrdering::SequentiallyConsistent:
2273InstructionSelector *
2277 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 bool isWorthFoldingAdd(SDValue Add)
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,...
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
constexpr bool isScalar() 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
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
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.
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,...
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.
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
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 isValid() const
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)
UnaryOp_match< SrcTy, TargetOpcode::G_INTTOPTR > m_GIntToPtr(const SrcTy &Src)
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_PTR_ADD, false > m_GPtrAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SHL, false > m_GShl(const LHS &L, const RHS &R)
GFrameIndexMatch m_GFrameIndex(int &FI)
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.
@ User
could "use" a pointer
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
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 int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
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.