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;
89 bool IsExternWeak =
false)
const;
97 unsigned &CurOp,
bool IsMasked,
98 bool IsStridedOrIndexed,
99 LLT *IndexVT =
nullptr)
const;
105 unsigned ShiftWidth)
const;
106 ComplexRendererFns selectShiftMaskXLen(
MachineOperand &Root)
const {
107 return selectShiftMask(Root, STI.
getXLen());
109 ComplexRendererFns selectShiftMask32(
MachineOperand &Root)
const {
110 return selectShiftMask(Root, 32);
113 ComplexRendererFns selectAddrRegImmLsb00000(
MachineOperand &Root)
const;
118 struct ConstAddrPlan {
119 enum { X0, LUI, InstSeq } Kind = X0;
124 ComplexRendererFns computeConstAddr(int64_t CVal,
bool IsPrefetch,
129 const ConstAddrPlan &Plan,
132 ComplexRendererFns selectSExtBits(
MachineOperand &Root,
unsigned Bits)
const;
133 template <
unsigned Bits>
135 return selectSExtBits(Root, Bits);
138 ComplexRendererFns selectZExtBits(
MachineOperand &Root,
unsigned Bits)
const;
139 template <
unsigned Bits>
141 return selectZExtBits(Root, Bits);
144 ComplexRendererFns selectSHXADDOp(
MachineOperand &Root,
unsigned ShAmt)
const;
145 template <
unsigned ShAmt>
147 return selectSHXADDOp(Root, ShAmt);
151 unsigned ShAmt)
const;
152 template <
unsigned ShAmt>
153 ComplexRendererFns selectSHXADD_UWOp(
MachineOperand &Root)
const {
154 return selectSHXADD_UWOp(Root, ShAmt);
192#define GET_GLOBALISEL_PREDICATES_DECL
193#include "RISCVGenGlobalISel.inc"
194#undef GET_GLOBALISEL_PREDICATES_DECL
196#define GET_GLOBALISEL_TEMPORARIES_DECL
197#include "RISCVGenGlobalISel.inc"
198#undef GET_GLOBALISEL_TEMPORARIES_DECL
203#define GET_GLOBALISEL_IMPL
204#include "RISCVGenGlobalISel.inc"
205#undef GET_GLOBALISEL_IMPL
207RISCVInstructionSelector::RISCVInstructionSelector(
210 : STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()), RBI(RBI),
214#include
"RISCVGenGlobalISel.inc"
217#include
"RISCVGenGlobalISel.inc"
223bool RISCVInstructionSelector::hasAllNBitUsers(
const MachineInstr &
MI,
225 const unsigned Depth)
const {
227 assert((
MI.getOpcode() == TargetOpcode::G_ADD ||
228 MI.getOpcode() == TargetOpcode::G_SUB ||
229 MI.getOpcode() == TargetOpcode::G_MUL ||
230 MI.getOpcode() == TargetOpcode::G_SHL ||
231 MI.getOpcode() == TargetOpcode::G_LSHR ||
232 MI.getOpcode() == TargetOpcode::G_AND ||
233 MI.getOpcode() == TargetOpcode::G_OR ||
234 MI.getOpcode() == TargetOpcode::G_XOR ||
235 MI.getOpcode() == TargetOpcode::G_SEXT_INREG ||
Depth != 0) &&
236 "Unexpected opcode");
238 if (
Depth >= RISCVInstructionSelector::MaxRecursionDepth)
241 auto DestReg =
MI.getOperand(0).getReg();
243 assert(UserOp.getParent() &&
"UserOp must have a parent");
244 const MachineInstr &UserMI = *UserOp.getParent();
245 unsigned OpIdx = UserOp.getOperandNo();
253 case RISCV::FCVT_D_W:
254 case RISCV::FCVT_S_W:
297InstructionSelector::ComplexRendererFns
298RISCVInstructionSelector::selectShiftMask(MachineOperand &Root,
299 unsigned ShiftWidth)
const {
303 using namespace llvm::MIPatternMatch;
309 ShAmtReg = ZExtSrcReg;
328 APInt ShMask(AndMask.
getBitWidth(), ShiftWidth - 1);
329 if (ShMask.isSubsetOf(AndMask)) {
330 ShAmtReg = AndSrcReg;
334 KnownBits
Known = VT->getKnownBits(AndSrcReg);
335 if (ShMask.isSubsetOf(AndMask |
Known.Zero))
336 ShAmtReg = AndSrcReg;
343 if (
Imm != 0 &&
Imm.urem(ShiftWidth) == 0)
348 if (
Imm != 0 &&
Imm.urem(ShiftWidth) == 0) {
352 unsigned NegOpc = Subtarget->
is64Bit() ? RISCV::SUBW : RISCV::SUB;
353 return {{[=](MachineInstrBuilder &MIB) {
354 MachineIRBuilder(*MIB.getInstr())
355 .buildInstr(NegOpc, {ShAmtReg}, {
Register(RISCV::X0),
Reg});
356 MIB.addReg(ShAmtReg);
359 if (
Imm.urem(ShiftWidth) == ShiftWidth - 1) {
363 return {{[=](MachineInstrBuilder &MIB) {
364 MachineIRBuilder(*MIB.getInstr())
365 .buildInstr(RISCV::XORI, {ShAmtReg}, {
Reg})
367 MIB.addReg(ShAmtReg);
372 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(ShAmtReg); }}};
375InstructionSelector::ComplexRendererFns
376RISCVInstructionSelector::selectSExtBits(MachineOperand &Root,
377 unsigned Bits)
const {
385 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(SrcReg); }}};
389 if ((
Size - VT->computeNumSignBits(RootReg)) < Bits)
390 return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
395InstructionSelector::ComplexRendererFns
396RISCVInstructionSelector::selectZExtBits(MachineOperand &Root,
397 unsigned Bits)
const {
405 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}};
410 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}};
414 return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
419InstructionSelector::ComplexRendererFns
420RISCVInstructionSelector::selectSHXADDOp(MachineOperand &Root,
421 unsigned ShAmt)
const {
422 using namespace llvm::MIPatternMatch;
428 const unsigned XLen = STI.
getXLen();
447 if (
Mask.isShiftedMask()) {
448 unsigned Leading = XLen -
Mask.getActiveBits();
449 unsigned Trailing =
Mask.countr_zero();
452 if (*LeftShift && Leading == 0 && C2.
ult(Trailing) && Trailing == ShAmt) {
454 return {{[=](MachineInstrBuilder &MIB) {
455 MachineIRBuilder(*MIB.getInstr())
456 .buildInstr(RISCV::SRLI, {DstReg}, {RegY})
464 if (!*LeftShift && Leading == C2 && Trailing == ShAmt) {
466 return {{[=](MachineInstrBuilder &MIB) {
467 MachineIRBuilder(*MIB.getInstr())
468 .buildInstr(RISCV::SRLI, {DstReg}, {RegY})
469 .addImm(Leading + Trailing);
490 unsigned Leading = XLen -
Mask.getActiveBits();
491 unsigned Trailing =
Mask.countr_zero();
505 return {{[=](MachineInstrBuilder &MIB) {
506 MachineIRBuilder(*MIB.getInstr())
507 .buildInstr(RISCV::SRLIW, {DstReg}, {RegY})
517InstructionSelector::ComplexRendererFns
518RISCVInstructionSelector::selectSHXADD_UWOp(MachineOperand &Root,
519 unsigned ShAmt)
const {
520 using namespace llvm::MIPatternMatch;
537 if (
Mask.isShiftedMask()) {
538 unsigned Leading =
Mask.countl_zero();
539 unsigned Trailing =
Mask.countr_zero();
540 if (Leading == 32 - ShAmt && C2 == Trailing && Trailing > ShAmt) {
542 return {{[=](MachineInstrBuilder &MIB) {
543 MachineIRBuilder(*MIB.getInstr())
544 .buildInstr(RISCV::SLLI, {DstReg}, {RegX})
555InstructionSelector::ComplexRendererFns
556RISCVInstructionSelector::renderVLOp(MachineOperand &Root)
const {
557 assert(Root.
isReg() &&
"Expected operand to be a Register");
558 std::optional<ValueAndVReg>
C;
560 if (
C->Value.isAllOnes())
564 return {{[=](MachineInstrBuilder &MIB) {
569 uint64_t ZExtC =
C->Value.getZExtValue();
570 return {{[=](MachineInstrBuilder &MIB) { MIB.addImm(ZExtC); }}};
573 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.
getReg()); }}};
576InstructionSelector::ComplexRendererFns
577RISCVInstructionSelector::selectAddrRegImm(MachineOperand &Root)
const {
582 if (RootDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX) {
584 [=](MachineInstrBuilder &MIB) { MIB.add(RootDef->
getOperand(1)); },
585 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
589 if (isBaseWithConstantOffset(Root, *MRI)) {
597 if (LHSDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX)
599 [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->
getOperand(1)); },
600 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
603 return {{[=](MachineInstrBuilder &MIB) { MIB.add(
LHS); },
604 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }}};
610 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.
getReg()); },
611 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
614InstructionSelector::ComplexRendererFns
615RISCVInstructionSelector::selectAddrRegImmLsb00000(MachineOperand &Root)
const {
620 if (RootDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX) {
622 [=](MachineInstrBuilder &MIB) { MIB.add(RootDef->
getOperand(1)); },
623 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
627 if (isBaseWithConstantOffset(Root, *MRI)) {
636 if ((RHSC & 0b11111) != 0) {
637 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.
getReg()); },
638 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
641 if (LHSDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX)
643 [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->
getOperand(1)); },
644 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
646 return {{[=](MachineInstrBuilder &MIB) { MIB.add(
LHS); },
647 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }}};
651 if ((-2049 >= RHSC && RHSC >= -4096) || (4063 >= RHSC && RHSC >= 2017)) {
652 int64_t Adj = RHSC < 0 ? -2048 : 2016;
653 int64_t AdjustedOffset = RHSC - Adj;
655 return {{[=](MachineInstrBuilder &MIB) {
658 BuildMI(*MIB->getParent(), *MIB.getInstr(),
659 MIB->getDebugLoc(),
TII.get(RISCV::ADDI), Tmp)
665 [=](MachineInstrBuilder &MIB) { MIB.addImm(Adj); }}};
670 if (
auto Fns = computeConstAddr(RHSC,
true,
LHS.getReg()))
676 if (RootDef->
getOpcode() == TargetOpcode::G_INTTOPTR) {
678 if (SrcDef->
getOpcode() == TargetOpcode::G_CONSTANT)
681 if (RootDef->
getOpcode() == TargetOpcode::G_CONSTANT) {
683 if (
auto Fns = computeConstAddr(CVal,
true,
Register()))
687 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.
getReg()); },
688 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
697 case CmpInst::Predicate::ICMP_EQ:
699 case CmpInst::Predicate::ICMP_NE:
701 case CmpInst::Predicate::ICMP_ULT:
703 case CmpInst::Predicate::ICMP_SLT:
705 case CmpInst::Predicate::ICMP_UGE:
707 case CmpInst::Predicate::ICMP_SGE:
773 CC = getRISCVCCFromICmp(Pred);
780 const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
785 return IsStore ? RISCV::SB_RL : RISCV::LB_AQ;
787 return IsStore ? RISCV::SH_RL : RISCV::LH_AQ;
789 return IsStore ? RISCV::SW_RL : RISCV::LW_AQ;
791 return IsStore ? RISCV::SD_RL : RISCV::LD_AQ;
799 const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
803 return IsStore ? RISCV::SB : RISCV::LBU;
805 return IsStore ? RISCV::SH : RISCV::LH;
807 return IsStore ? RISCV::SW : RISCV::LW;
809 return IsStore ? RISCV::SD : RISCV::LD;
815void RISCVInstructionSelector::addVectorLoadStoreOperands(
816 MachineInstr &
I, SmallVectorImpl<Register> &SrcOps,
unsigned &CurOp,
817 bool IsMasked,
bool IsStridedOrIndexed, LLT *IndexVT)
const {
819 auto PtrReg =
I.getOperand(CurOp++).getReg();
823 if (IsStridedOrIndexed) {
824 auto StrideReg =
I.getOperand(CurOp++).getReg();
827 *IndexVT = MRI->
getType(StrideReg);
832 auto MaskReg =
I.getOperand(CurOp++).getReg();
837bool RISCVInstructionSelector::selectIntrinsicWithSideEffects(
838 MachineInstr &
I)
const {
845 case Intrinsic::riscv_vlm:
846 case Intrinsic::riscv_vle:
847 case Intrinsic::riscv_vle_mask:
848 case Intrinsic::riscv_vlse:
849 case Intrinsic::riscv_vlse_mask: {
850 bool IsMasked = IntrinID == Intrinsic::riscv_vle_mask ||
851 IntrinID == Intrinsic::riscv_vlse_mask;
852 bool IsStrided = IntrinID == Intrinsic::riscv_vlse ||
853 IntrinID == Intrinsic::riscv_vlse_mask;
854 LLT VT = MRI->
getType(
I.getOperand(0).getReg());
858 const Register DstReg =
I.getOperand(0).getReg();
861 bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
866 if (HasPassthruOperand) {
867 auto PassthruReg =
I.getOperand(CurOp++).getReg();
873 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked, IsStrided);
876 const RISCV::VLEPseudo *
P =
877 RISCV::getVLEPseudo(IsMasked, IsStrided,
false, Log2SEW,
878 static_cast<unsigned>(LMUL));
880 MachineInstrBuilder PseudoMI =
881 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(
P->Pseudo), DstReg);
886 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
887 for (
auto &RenderFn : *VLOpFn)
896 Policy =
I.getOperand(CurOp++).getImm();
906 case Intrinsic::riscv_vloxei:
907 case Intrinsic::riscv_vloxei_mask:
908 case Intrinsic::riscv_vluxei:
909 case Intrinsic::riscv_vluxei_mask: {
910 bool IsMasked = IntrinID == Intrinsic::riscv_vloxei_mask ||
911 IntrinID == Intrinsic::riscv_vluxei_mask;
912 bool IsOrdered = IntrinID == Intrinsic::riscv_vloxei ||
913 IntrinID == Intrinsic::riscv_vloxei_mask;
914 LLT VT = MRI->
getType(
I.getOperand(0).getReg());
918 const Register DstReg =
I.getOperand(0).getReg();
921 bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
926 if (HasPassthruOperand) {
927 auto PassthruReg =
I.getOperand(CurOp++).getReg();
934 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked,
true, &IndexVT);
940 if (IndexLog2EEW == 6 && !Subtarget->
is64Bit()) {
942 "values when XLEN=32");
944 const RISCV::VLX_VSXPseudo *
P = RISCV::getVLXPseudo(
945 IsMasked, IsOrdered, IndexLog2EEW,
static_cast<unsigned>(LMUL),
946 static_cast<unsigned>(IndexLMUL));
948 MachineInstrBuilder PseudoMI =
949 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(
P->Pseudo), DstReg);
954 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
955 for (
auto &RenderFn : *VLOpFn)
964 Policy =
I.getOperand(CurOp++).getImm();
974 case Intrinsic::riscv_vsm:
975 case Intrinsic::riscv_vse:
976 case Intrinsic::riscv_vse_mask:
977 case Intrinsic::riscv_vsse:
978 case Intrinsic::riscv_vsse_mask: {
979 bool IsMasked = IntrinID == Intrinsic::riscv_vse_mask ||
980 IntrinID == Intrinsic::riscv_vsse_mask;
981 bool IsStrided = IntrinID == Intrinsic::riscv_vsse ||
982 IntrinID == Intrinsic::riscv_vsse_mask;
983 LLT VT = MRI->
getType(
I.getOperand(1).getReg());
991 auto PassthruReg =
I.getOperand(CurOp++).getReg();
994 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked, IsStrided);
997 const RISCV::VSEPseudo *
P = RISCV::getVSEPseudo(
998 IsMasked, IsStrided, Log2SEW,
static_cast<unsigned>(LMUL));
1000 MachineInstrBuilder PseudoMI =
1006 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
1007 for (
auto &RenderFn : *VLOpFn)
1011 PseudoMI.
addImm(Log2SEW);
1016 I.eraseFromParent();
1020 case Intrinsic::riscv_vsoxei:
1021 case Intrinsic::riscv_vsoxei_mask:
1022 case Intrinsic::riscv_vsuxei:
1023 case Intrinsic::riscv_vsuxei_mask: {
1024 bool IsMasked = IntrinID == Intrinsic::riscv_vsoxei_mask ||
1025 IntrinID == Intrinsic::riscv_vsuxei_mask;
1026 bool IsOrdered = IntrinID == Intrinsic::riscv_vsoxei ||
1027 IntrinID == Intrinsic::riscv_vsoxei_mask;
1028 LLT VT = MRI->
getType(
I.getOperand(1).getReg());
1036 auto PassthruReg =
I.getOperand(CurOp++).getReg();
1040 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked,
true, &IndexVT);
1046 if (IndexLog2EEW == 6 && !Subtarget->
is64Bit()) {
1048 "values when XLEN=32");
1050 const RISCV::VLX_VSXPseudo *
P = RISCV::getVSXPseudo(
1051 IsMasked, IsOrdered, IndexLog2EEW,
static_cast<unsigned>(LMUL),
1052 static_cast<unsigned>(IndexLMUL));
1054 MachineInstrBuilder PseudoMI =
1060 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
1061 for (
auto &RenderFn : *VLOpFn)
1065 PseudoMI.
addImm(Log2SEW);
1070 I.eraseFromParent();
1077bool RISCVInstructionSelector::selectIntrinsic(MachineInstr &
I)
const {
1084 case Intrinsic::riscv_vsetvli:
1085 case Intrinsic::riscv_vsetvlimax: {
1087 bool VLMax = IntrinID == Intrinsic::riscv_vsetvlimax;
1089 unsigned Offset = VLMax ? 2 : 3;
1097 Register DstReg =
I.getOperand(0).getReg();
1100 unsigned Opcode = RISCV::PseudoVSETVLI;
1104 Register AVLReg =
I.getOperand(2).getReg();
1106 uint64_t AVL = AVLConst->Value.getZExtValue();
1119 Opcode = RISCV::PseudoVSETVLIX0;
1121 Register AVLReg =
I.getOperand(2).getReg();
1126 uint64_t AVL = AVLConst->Value.getZExtValue();
1128 MachineInstr *PseudoMI =
1130 TII.get(RISCV::PseudoVSETIVLI), DstReg)
1133 I.eraseFromParent();
1140 MachineInstr *PseudoMI =
1141 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode), DstReg)
1144 I.eraseFromParent();
1151bool RISCVInstructionSelector::selectExtractSubvector(MachineInstr &
MI)
const {
1152 assert(
MI.getOpcode() == TargetOpcode::G_EXTRACT_SUBVECTOR);
1157 LLT DstTy = MRI->
getType(DstReg);
1158 LLT SrcTy = MRI->
getType(SrcReg);
1160 unsigned Idx =
static_cast<unsigned>(
MI.getOperand(2).
getImm());
1166 std::tie(SubRegIdx, Idx) =
1168 SrcMVT, DstMVT, Idx, &
TRI);
1183 BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1185 .
addReg(SrcReg, {}, SubRegIdx);
1187 MI.eraseFromParent();
1191bool RISCVInstructionSelector::selectInsertSubVector(MachineInstr &
MI)
const {
1192 assert(
MI.getOpcode() == TargetOpcode::G_INSERT_SUBVECTOR);
1196 Register SubVecReg =
MI.getOperand(2).getReg();
1198 LLT VecTy = MRI->
getType(VecReg);
1199 LLT SubVecTy = MRI->
getType(SubVecReg);
1204 unsigned Idx =
static_cast<unsigned>(
MI.getOperand(3).
getImm());
1207 std::tie(SubRegIdx, Idx) =
1209 VecMVT, SubVecMVT, Idx, &
TRI);
1225 if (SubRegIdx == RISCV::NoSubRegister) {
1228 "Unexpected subvector insert");
1229 BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1232 MI.eraseFromParent();
1238 MachineInstr *Ins =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1239 TII.get(TargetOpcode::INSERT_SUBREG), DstReg)
1244 MI.eraseFromParent();
1249bool RISCVInstructionSelector::select(MachineInstr &
MI) {
1251 const unsigned Opc =
MI.getOpcode();
1253 if (!
MI.isPreISelOpcode() ||
Opc == TargetOpcode::G_PHI) {
1254 if (
Opc == TargetOpcode::PHI ||
Opc == TargetOpcode::G_PHI) {
1255 const Register DefReg =
MI.getOperand(0).getReg();
1256 const LLT DefTy = MRI->
getType(DefReg);
1270 DefRC =
TRI.getRegClassForTypeOnBank(DefTy, RB, STI.
is64Bit());
1277 MI.setDesc(
TII.get(TargetOpcode::PHI));
1288 if (selectImpl(
MI, *CoverageInfo))
1292 case TargetOpcode::G_ANYEXT:
1293 case TargetOpcode::G_PTRTOINT:
1294 case TargetOpcode::G_INTTOPTR:
1295 case TargetOpcode::G_TRUNC:
1296 case TargetOpcode::G_FREEZE:
1298 case TargetOpcode::G_CONSTANT: {
1300 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
1302 if (!materializeImm(DstReg,
Imm,
MI))
1305 MI.eraseFromParent();
1308 case TargetOpcode::G_ZEXT:
1309 case TargetOpcode::G_SEXT: {
1310 bool IsSigned =
Opc != TargetOpcode::G_ZEXT;
1313 LLT SrcTy = MRI->
getType(SrcReg);
1320 RISCV::GPRBRegBankID &&
1321 "Unexpected ext regbank");
1324 if (IsSigned && SrcSize == 32) {
1325 MI.setDesc(
TII.get(RISCV::ADDIW));
1332 if (!IsSigned && SrcSize == 32 && STI.hasStdExtZba()) {
1333 MI.setDesc(
TII.get(RISCV::ADD_UW));
1340 if (SrcSize == 16 &&
1341 (STI.hasStdExtZbb() || (!IsSigned && STI.hasStdExtZbkb()))) {
1342 MI.setDesc(
TII.get(IsSigned ? RISCV::SEXT_H
1343 : STI.isRV64() ? RISCV::ZEXT_H_RV64
1344 : RISCV::ZEXT_H_RV32));
1351 MachineInstr *ShiftLeft =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1352 TII.get(RISCV::SLLI), ShiftLeftReg)
1356 MachineInstr *ShiftRight =
1358 TII.get(IsSigned ? RISCV::SRAI : RISCV::SRLI), DstReg)
1362 MI.eraseFromParent();
1365 case TargetOpcode::G_FCONSTANT: {
1368 const APFloat &FPimm =
MI.getOperand(1).getFPImm()->getValueAPF();
1377 if (!materializeImm(GPRReg,
Imm.getSExtValue(),
MI))
1381 unsigned Opcode =
Size == 64 ? RISCV::FMV_D_X
1382 :
Size == 32 ? RISCV::FMV_W_X
1384 MachineInstr *FMV =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1385 TII.get(Opcode), DstReg)
1391 "Unexpected size or subtarget");
1395 MachineInstr *FCVT =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1396 TII.get(RISCV::FCVT_D_W), DstReg)
1401 MI.eraseFromParent();
1409 if (!materializeImm(GPRRegHigh,
Imm.extractBits(32, 32).getSExtValue(),
1412 if (!materializeImm(GPRRegLow,
Imm.trunc(32).getSExtValue(),
MI))
1414 MachineInstr *PairF64 =
1416 TII.get(RISCV::BuildPairF64Pseudo), DstReg)
1422 MI.eraseFromParent();
1425 case TargetOpcode::G_GLOBAL_VALUE: {
1426 auto *GV =
MI.getOperand(1).getGlobal();
1427 if (GV->isThreadLocal()) {
1432 return selectAddr(
MI, GV->isDSOLocal(), GV->hasExternalWeakLinkage());
1434 case TargetOpcode::G_JUMP_TABLE:
1435 case TargetOpcode::G_CONSTANT_POOL:
1436 return selectAddr(
MI);
1437 case TargetOpcode::G_BRCOND: {
1442 MachineInstr *Bcc =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1446 .
addMBB(
MI.getOperand(1).getMBB());
1447 MI.eraseFromParent();
1451 case TargetOpcode::G_BRINDIRECT:
1452 MI.setDesc(
TII.get(RISCV::PseudoBRIND));
1456 case TargetOpcode::G_SELECT:
1457 return selectSelect(
MI);
1458 case TargetOpcode::G_FCMP:
1459 return selectFPCompare(
MI);
1460 case TargetOpcode::G_FENCE: {
1465 emitFence(FenceOrdering, FenceSSID,
MI);
1466 MI.eraseFromParent();
1469 case TargetOpcode::G_IMPLICIT_DEF:
1470 return selectImplicitDef(
MI);
1471 case TargetOpcode::G_UNMERGE_VALUES:
1473 case TargetOpcode::G_LOAD:
1474 case TargetOpcode::G_STORE: {
1478 LLT PtrTy = MRI->
getType(PtrReg);
1480 const RegisterBank &RB = *RBI.
getRegBank(ValReg, *MRI,
TRI);
1481 if (RB.
getID() != RISCV::GPRBRegBankID)
1485 const RegisterBank &PtrRB = *RBI.
getRegBank(PtrReg, *MRI,
TRI);
1488 "Load/Store pointer operand isn't a GPR");
1489 assert(PtrTy.
isPointer() &&
"Load/Store pointer operand isn't a pointer");
1506 if (NewOpc ==
MI.getOpcode())
1510 auto AddrModeFns = selectAddrRegImm(
MI.getOperand(1));
1515 MachineInstrBuilder NewInst =
1523 for (
auto &Fn : *AddrModeFns)
1525 MI.eraseFromParent();
1530 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
1531 return selectIntrinsicWithSideEffects(
MI);
1532 case TargetOpcode::G_INTRINSIC:
1533 return selectIntrinsic(
MI);
1534 case TargetOpcode::G_EXTRACT_SUBVECTOR:
1535 return selectExtractSubvector(
MI);
1536 case TargetOpcode::G_INSERT_SUBVECTOR:
1537 return selectInsertSubVector(
MI);
1543bool RISCVInstructionSelector::selectUnmergeValues(MachineInstr &
MI)
const {
1544 assert(
MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
1546 if (!Subtarget->hasStdExtZfa())
1550 if (
MI.getNumOperands() != 3)
1555 if (!isRegInFprb(Src) || !isRegInGprb(
Lo) || !isRegInGprb(
Hi))
1558 MachineInstr *ExtractLo =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1559 TII.get(RISCV::FMV_X_W_FPR64),
Lo)
1563 MachineInstr *ExtractHi =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1564 TII.get(RISCV::FMVH_X_D),
Hi)
1568 MI.eraseFromParent();
1572bool RISCVInstructionSelector::replacePtrWithInt(MachineInstr &
MI,
1574 MachineOperand &
Op =
MI.getOperand(OpIdx);
1581 MachineInstr *PtrToInt =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1582 TII.get(TargetOpcode::G_PTRTOINT), IntReg)
1585 return select(*PtrToInt);
1588void RISCVInstructionSelector::preISelLower(MachineInstr &
MI) {
1589 switch (
MI.getOpcode()) {
1590 case TargetOpcode::G_PTR_ADD: {
1594 replacePtrWithInt(
MI, 1);
1595 MI.setDesc(
TII.get(TargetOpcode::G_ADD));
1599 case TargetOpcode::G_PTRMASK: {
1602 replacePtrWithInt(
MI, 1);
1603 MI.setDesc(
TII.get(TargetOpcode::G_AND));
1610void RISCVInstructionSelector::renderNegImm(MachineInstrBuilder &MIB,
1611 const MachineInstr &
MI,
1613 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1614 "Expected G_CONSTANT");
1615 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
1619void RISCVInstructionSelector::renderImmSubFromXLen(MachineInstrBuilder &MIB,
1620 const MachineInstr &
MI,
1622 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1623 "Expected G_CONSTANT");
1624 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
1628void RISCVInstructionSelector::renderImmSubFrom32(MachineInstrBuilder &MIB,
1629 const MachineInstr &
MI,
1631 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1632 "Expected G_CONSTANT");
1633 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
1637void RISCVInstructionSelector::renderImmPlus1(MachineInstrBuilder &MIB,
1638 const MachineInstr &
MI,
1640 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1641 "Expected G_CONSTANT");
1642 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
1646void RISCVInstructionSelector::renderTrailingZeros(MachineInstrBuilder &MIB,
1647 const MachineInstr &
MI,
1649 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1650 "Expected G_CONSTANT");
1651 uint64_t C =
MI.getOperand(1).getCImm()->getZExtValue();
1655void RISCVInstructionSelector::renderXLenSubTrailingOnes(
1656 MachineInstrBuilder &MIB,
const MachineInstr &
MI,
int OpIdx)
const {
1657 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1658 "Expected G_CONSTANT");
1659 uint64_t C =
MI.getOperand(1).getCImm()->getZExtValue();
1663void RISCVInstructionSelector::renderAddiPairImmSmall(MachineInstrBuilder &MIB,
1664 const MachineInstr &
MI,
1666 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1667 "Expected G_CONSTANT");
1668 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
1669 int64_t Adj =
Imm < 0 ? -2048 : 2047;
1673void RISCVInstructionSelector::renderAddiPairImmLarge(MachineInstrBuilder &MIB,
1674 const MachineInstr &
MI,
1676 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1677 "Expected G_CONSTANT");
1678 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue() < 0 ? -2048 : 2047;
1682bool RISCVInstructionSelector::isRegInGprb(
Register Reg)
const {
1686bool RISCVInstructionSelector::isRegInFprb(
Register Reg)
const {
1690bool RISCVInstructionSelector::selectCopy(MachineInstr &
MI)
const {
1697 TRI.getConstrainedRegClassForReg(DstReg, *MRI);
1700 "Register class not available for LLT, register bank combination");
1711 MI.setDesc(
TII.get(RISCV::COPY));
1715bool RISCVInstructionSelector::selectImplicitDef(MachineInstr &
MI)
const {
1716 assert(
MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
1718 const Register DstReg =
MI.getOperand(0).getReg();
1723 "Register class not available for LLT, register bank combination");
1729 MI.setDesc(
TII.get(TargetOpcode::IMPLICIT_DEF));
1733bool RISCVInstructionSelector::materializeImm(
Register DstReg, int64_t
Imm,
1734 MachineInstr &
MI)
const {
1744 return materializeInstSeq(DstReg, Seq,
MI);
1747bool RISCVInstructionSelector::materializeInstSeq(
1749 assert(!Seq.
empty() &&
"materializeInstSeq requires a non-empty sequence");
1753 unsigned NumInsts = Seq.
size();
1756 for (
unsigned i = 0; i < NumInsts; i++) {
1760 const RISCVMatInt::Inst &
I = Seq[i];
1763 switch (
I.getOpndKind()) {
1793InstructionSelector::ComplexRendererFns
1794RISCVInstructionSelector::computeConstAddr(int64_t CVal,
bool IsPrefetch,
1801 auto emit = [&](ConstAddrPlan Plan) -> ComplexRendererFns {
1802 return {{[=](MachineInstrBuilder &MIB) {
1803 MIB.
addReg(materializeConstBase(MIB, Plan, OrigBase));
1805 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Plan.Lo12); }}};
1808 if (IsPrefetch && (Lo12 & 0b11111) != 0)
1809 return std::nullopt;
1813 Plan.Kind = ConstAddrPlan::LUI;
1814 Plan.Hi20 = (
Hi >> 12) & 0xfffff;
1816 return emit(std::move(Plan));
1822 if (Seq.
back().getOpcode() != RISCV::ADDI)
1823 return std::nullopt;
1824 Lo12 = Seq.
back().getImm();
1825 if (IsPrefetch && (Lo12 & 0b11111) != 0)
1826 return std::nullopt;
1829 return std::nullopt;
1831 Plan.Kind = ConstAddrPlan::InstSeq;
1832 Plan.Seq = std::move(Seq);
1834 return emit(std::move(Plan));
1838RISCVInstructionSelector::materializeConstBase(MachineInstrBuilder &MIB,
1839 const ConstAddrPlan &Plan,
1843 MachineInstr &InsertPt = *MIB.
getInstr();
1846 switch (Plan.Kind) {
1847 case ConstAddrPlan::X0:
1849 case ConstAddrPlan::LUI: {
1851 MachineInstr *LUI =
BuildMI(
MBB, InsertPt,
DL,
TII.get(RISCV::LUI), HiReg)
1856 case ConstAddrPlan::InstSeq: {
1858 materializeInstSeq(HiReg, Plan.Seq, InsertPt);
1865 if (OrigBase.
isValid() && HiReg != RISCV::X0) {
1873 return OrigBase.
isValid() ? OrigBase : HiReg;
1876bool RISCVInstructionSelector::selectAddr(MachineInstr &
MI,
bool IsLocal,
1877 bool IsExternWeak)
const {
1878 assert((
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
1879 MI.getOpcode() == TargetOpcode::G_JUMP_TABLE ||
1880 MI.getOpcode() == TargetOpcode::G_CONSTANT_POOL) &&
1881 "Unexpected opcode");
1883 const MachineOperand &DispMO =
MI.getOperand(1);
1886 const LLT DefTy = MRI->
getType(DefReg);
1893 if (IsLocal && !Subtarget->allowTaggedGlobals()) {
1897 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1914 TII.get(RISCV::PseudoLGA), DefReg)
1920 MI.eraseFromParent();
1927 "Unsupported code model for lowering",
MI);
1935 MachineInstr *AddrHi =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1936 TII.get(RISCV::LUI), AddrHiDest)
1942 TII.get(RISCV::ADDI), DefReg)
1948 MI.eraseFromParent();
1969 TII.get(RISCV::PseudoLGA), DefReg)
1975 MI.eraseFromParent();
1982 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1990bool RISCVInstructionSelector::selectSelect(MachineInstr &
MI)
const {
1997 Register DstReg = SelectMI.getReg(0);
1999 unsigned Opc = RISCV::Select_GPR_Using_CC_GPR;
2002 Opc =
Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR
2003 : RISCV::Select_FPR64_Using_CC_GPR;
2012 .
addReg(SelectMI.getTrueReg())
2013 .
addReg(SelectMI.getFalseReg());
2014 MI.eraseFromParent();
2026 return Size == 16 ? RISCV::FLT_H :
Size == 32 ? RISCV::FLT_S : RISCV::FLT_D;
2028 return Size == 16 ? RISCV::FLE_H :
Size == 32 ? RISCV::FLE_S : RISCV::FLE_D;
2030 return Size == 16 ? RISCV::FEQ_H :
Size == 32 ? RISCV::FEQ_S : RISCV::FEQ_D;
2043 assert(!isLegalFCmpPredicate(Pred) &&
"Predicate already legal?");
2046 if (isLegalFCmpPredicate(InvPred)) {
2054 if (isLegalFCmpPredicate(InvPred)) {
2059 if (isLegalFCmpPredicate(InvPred)) {
2071bool RISCVInstructionSelector::selectFPCompare(MachineInstr &
MI)
const {
2084 bool NeedInvert =
false;
2098 MachineInstr *Cmp1 =
2105 MachineInstr *Cmp2 =
2114 TII.get(RISCV::OR), TmpReg)
2133 MachineInstr *Cmp1 =
2140 MachineInstr *Cmp2 =
2147 TII.get(RISCV::AND), TmpReg)
2158 TII.get(RISCV::XORI), DstReg)
2164 MI.eraseFromParent();
2168void RISCVInstructionSelector::emitFence(
AtomicOrdering FenceOrdering,
2170 MachineInstr &
MI)
const {
2174 if (STI.hasStdExtZtso()) {
2177 if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
2201 unsigned Pred, Succ;
2202 switch (FenceOrdering) {
2205 case AtomicOrdering::AcquireRelease:
2209 case AtomicOrdering::Acquire:
2214 case AtomicOrdering::Release:
2219 case AtomicOrdering::SequentiallyConsistent:
2229InstructionSelector *
2233 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
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.
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 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)
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.
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.