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);
115 ComplexRendererFns selectAddrRegImmLsb00000(
MachineOperand &Root)
const;
120 struct ConstAddrPlan {
121 enum { X0, LUI, InstSeq } Kind = X0;
126 ComplexRendererFns computeConstAddr(int64_t CVal,
bool IsPrefetch,
131 const ConstAddrPlan &Plan,
134 ComplexRendererFns selectSExtBits(
MachineOperand &Root,
unsigned Bits)
const;
135 template <
unsigned Bits>
137 return selectSExtBits(Root, Bits);
140 ComplexRendererFns selectZExtBits(
MachineOperand &Root,
unsigned Bits)
const;
141 template <
unsigned Bits>
143 return selectZExtBits(Root, Bits);
146 ComplexRendererFns selectSHXADDOp(
MachineOperand &Root,
unsigned ShAmt)
const;
147 template <
unsigned ShAmt>
149 return selectSHXADDOp(Root, ShAmt);
153 unsigned ShAmt)
const;
154 template <
unsigned ShAmt>
155 ComplexRendererFns selectSHXADD_UWOp(
MachineOperand &Root)
const {
156 return selectSHXADD_UWOp(Root, ShAmt);
160 ComplexRendererFns renderAddiPair(
Register BaseReg, int64_t AddiImm,
161 int64_t OffsetImm)
const;
195#define GET_GLOBALISEL_PREDICATES_DECL
196#include "RISCVGenGlobalISel.inc"
197#undef GET_GLOBALISEL_PREDICATES_DECL
199#define GET_GLOBALISEL_TEMPORARIES_DECL
200#include "RISCVGenGlobalISel.inc"
201#undef GET_GLOBALISEL_TEMPORARIES_DECL
206#define GET_GLOBALISEL_IMPL
207#include "RISCVGenGlobalISel.inc"
208#undef GET_GLOBALISEL_IMPL
210RISCVInstructionSelector::RISCVInstructionSelector(
213 : STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()), RBI(RBI),
217#include
"RISCVGenGlobalISel.inc"
220#include
"RISCVGenGlobalISel.inc"
226bool RISCVInstructionSelector::hasAllNBitUsers(
const MachineInstr &
MI,
228 const unsigned Depth)
const {
230 assert((
MI.getOpcode() == TargetOpcode::G_ADD ||
231 MI.getOpcode() == TargetOpcode::G_SUB ||
232 MI.getOpcode() == TargetOpcode::G_MUL ||
233 MI.getOpcode() == TargetOpcode::G_SHL ||
234 MI.getOpcode() == TargetOpcode::G_LSHR ||
235 MI.getOpcode() == TargetOpcode::G_AND ||
236 MI.getOpcode() == TargetOpcode::G_OR ||
237 MI.getOpcode() == TargetOpcode::G_XOR ||
238 MI.getOpcode() == TargetOpcode::G_SEXT_INREG ||
Depth != 0) &&
239 "Unexpected opcode");
241 if (
Depth >= RISCVInstructionSelector::MaxRecursionDepth)
244 auto DestReg =
MI.getOperand(0).getReg();
246 assert(UserOp.getParent() &&
"UserOp must have a parent");
247 const MachineInstr &UserMI = *UserOp.getParent();
248 unsigned OpIdx = UserOp.getOperandNo();
256 case RISCV::FCVT_D_W:
257 case RISCV::FCVT_S_W:
300InstructionSelector::ComplexRendererFns
301RISCVInstructionSelector::selectShiftMask(MachineOperand &Root,
302 unsigned ShiftWidth)
const {
306 using namespace llvm::MIPatternMatch;
312 ShAmtReg = ZExtSrcReg;
331 APInt ShMask(AndMask.
getBitWidth(), ShiftWidth - 1);
332 if (ShMask.isSubsetOf(AndMask)) {
333 ShAmtReg = AndSrcReg;
337 KnownBits
Known = VT->getKnownBits(AndSrcReg);
338 if (ShMask.isSubsetOf(AndMask |
Known.Zero))
339 ShAmtReg = AndSrcReg;
346 if (
Imm != 0 &&
Imm.urem(ShiftWidth) == 0)
351 if (
Imm != 0 &&
Imm.urem(ShiftWidth) == 0) {
355 unsigned NegOpc = Subtarget->
is64Bit() ? RISCV::SUBW : RISCV::SUB;
356 return {{[=](MachineInstrBuilder &MIB) {
357 MachineIRBuilder(*MIB.getInstr())
358 .buildInstr(NegOpc, {ShAmtReg}, {
Register(RISCV::X0),
Reg});
359 MIB.addReg(ShAmtReg);
362 if (
Imm.urem(ShiftWidth) == ShiftWidth - 1) {
366 return {{[=](MachineInstrBuilder &MIB) {
367 MachineIRBuilder(*MIB.getInstr())
368 .buildInstr(RISCV::XORI, {ShAmtReg}, {
Reg})
370 MIB.addReg(ShAmtReg);
375 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(ShAmtReg); }}};
378InstructionSelector::ComplexRendererFns
379RISCVInstructionSelector::selectSExtBits(MachineOperand &Root,
380 unsigned Bits)
const {
388 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(SrcReg); }}};
392 if ((
Size - VT->computeNumSignBits(RootReg)) < Bits)
393 return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
398InstructionSelector::ComplexRendererFns
399RISCVInstructionSelector::selectZExtBits(MachineOperand &Root,
400 unsigned Bits)
const {
408 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}};
413 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}};
417 return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
422InstructionSelector::ComplexRendererFns
423RISCVInstructionSelector::selectSHXADDOp(MachineOperand &Root,
424 unsigned ShAmt)
const {
425 using namespace llvm::MIPatternMatch;
431 const unsigned XLen = STI.
getXLen();
450 if (
Mask.isShiftedMask()) {
451 unsigned Leading = XLen -
Mask.getActiveBits();
452 unsigned Trailing =
Mask.countr_zero();
455 if (*LeftShift && Leading == 0 && C2.
ult(Trailing) && Trailing == ShAmt) {
457 return {{[=](MachineInstrBuilder &MIB) {
458 MachineIRBuilder(*MIB.getInstr())
459 .buildInstr(RISCV::SRLI, {DstReg}, {RegY})
467 if (!*LeftShift && Leading == C2 && Trailing == ShAmt) {
469 return {{[=](MachineInstrBuilder &MIB) {
470 MachineIRBuilder(*MIB.getInstr())
471 .buildInstr(RISCV::SRLI, {DstReg}, {RegY})
472 .addImm(Leading + Trailing);
493 unsigned Leading = XLen -
Mask.getActiveBits();
494 unsigned Trailing =
Mask.countr_zero();
508 return {{[=](MachineInstrBuilder &MIB) {
509 MachineIRBuilder(*MIB.getInstr())
510 .buildInstr(RISCV::SRLIW, {DstReg}, {RegY})
520InstructionSelector::ComplexRendererFns
521RISCVInstructionSelector::selectSHXADD_UWOp(MachineOperand &Root,
522 unsigned ShAmt)
const {
523 using namespace llvm::MIPatternMatch;
540 if (
Mask.isShiftedMask()) {
541 unsigned Leading =
Mask.countl_zero();
542 unsigned Trailing =
Mask.countr_zero();
543 if (Leading == 32 - ShAmt && C2 == Trailing && Trailing > ShAmt) {
545 return {{[=](MachineInstrBuilder &MIB) {
546 MachineIRBuilder(*MIB.getInstr())
547 .buildInstr(RISCV::SLLI, {DstReg}, {RegX})
558InstructionSelector::ComplexRendererFns
559RISCVInstructionSelector::renderVLOp(MachineOperand &Root)
const {
560 assert(Root.
isReg() &&
"Expected operand to be a Register");
561 std::optional<ValueAndVReg>
C;
563 if (
C->Value.isAllOnes())
567 return {{[=](MachineInstrBuilder &MIB) {
572 uint64_t ZExtC =
C->Value.getZExtValue();
573 return {{[=](MachineInstrBuilder &MIB) { MIB.addImm(ZExtC); }}};
576 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.
getReg()); }}};
579InstructionSelector::ComplexRendererFns
580RISCVInstructionSelector::renderAddiPair(
Register BaseReg, int64_t AddiImm,
581 int64_t OffsetImm)
const {
582 return {{[=](MachineInstrBuilder &MIB) {
585 BuildMI(*MIB->getParent(), *MIB.getInstr(), MIB->getDebugLoc(),
586 TII.get(RISCV::ADDI), Tmp)
592 [=](MachineInstrBuilder &MIB) { MIB.addImm(OffsetImm); }}};
595InstructionSelector::ComplexRendererFns
596RISCVInstructionSelector::selectAddrRegImm(MachineOperand &Root)
const {
606 [=](MachineInstrBuilder &MIB) { MIB.addFrameIndex(FI); },
607 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
619 [=](MachineInstrBuilder &MIB) { MIB.addFrameIndex(BaseFI); },
620 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
623 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(BaseReg); },
624 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }}};
629 if (RHSC >= -4096 && RHSC <= 4094) {
630 int64_t Adj = RHSC < 0 ? -2048 : 2047;
631 return renderAddiPair(BaseReg, Adj, RHSC - Adj);
635 if (
auto Fns = computeConstAddr(RHSC,
false, BaseReg))
644 if (
auto Fns = computeConstAddr(CVal,
false,
Register()))
648 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RootReg); },
649 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
652InstructionSelector::ComplexRendererFns
653RISCVInstructionSelector::selectBrindRegImm(MachineOperand &Root)
const {
666 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(BaseReg); },
667 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }}};
670 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RootReg); },
671 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
674InstructionSelector::ComplexRendererFns
675RISCVInstructionSelector::selectAddrRegImmLsb00000(MachineOperand &Root)
const {
685 [=](MachineInstrBuilder &MIB) { MIB.addFrameIndex(FI); },
686 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
696 if ((RHSC & 0b11111) != 0) {
697 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RootReg); },
698 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
704 [=](MachineInstrBuilder &MIB) { MIB.addFrameIndex(BaseFI); },
705 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
707 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(BaseReg); },
708 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }}};
712 if ((-2049 >= RHSC && RHSC >= -4096) || (4063 >= RHSC && RHSC >= 2017)) {
713 int64_t Adj = RHSC < 0 ? -2048 : 2016;
714 return renderAddiPair(BaseReg, RHSC - Adj, Adj);
719 if (
auto Fns = computeConstAddr(RHSC,
true, BaseReg))
728 if (
auto Fns = computeConstAddr(CVal,
true,
Register()))
732 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RootReg); },
733 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
742 case CmpInst::Predicate::ICMP_EQ:
744 case CmpInst::Predicate::ICMP_NE:
746 case CmpInst::Predicate::ICMP_ULT:
748 case CmpInst::Predicate::ICMP_SLT:
750 case CmpInst::Predicate::ICMP_UGE:
752 case CmpInst::Predicate::ICMP_SGE:
818 CC = getRISCVCCFromICmp(Pred);
825 const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
830 return IsStore ? RISCV::SB_RL : RISCV::LB_AQ;
832 return IsStore ? RISCV::SH_RL : RISCV::LH_AQ;
834 return IsStore ? RISCV::SW_RL : RISCV::LW_AQ;
836 return IsStore ? RISCV::SD_RL : RISCV::LD_AQ;
844 const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
848 return IsStore ? RISCV::SB : RISCV::LBU;
850 return IsStore ? RISCV::SH : RISCV::LH;
852 return IsStore ? RISCV::SW : RISCV::LW;
854 return IsStore ? RISCV::SD : RISCV::LD;
860void RISCVInstructionSelector::addVectorLoadStoreOperands(
861 MachineInstr &
I, SmallVectorImpl<Register> &SrcOps,
unsigned &CurOp,
862 bool IsMasked,
bool IsStridedOrIndexed, LLT *IndexVT)
const {
864 auto PtrReg =
I.getOperand(CurOp++).getReg();
868 if (IsStridedOrIndexed) {
869 auto StrideReg =
I.getOperand(CurOp++).getReg();
872 *IndexVT = MRI->
getType(StrideReg);
877 auto MaskReg =
I.getOperand(CurOp++).getReg();
882bool RISCVInstructionSelector::selectIntrinsicWithSideEffects(
883 MachineInstr &
I)
const {
890 case Intrinsic::riscv_vlm:
891 case Intrinsic::riscv_vle:
892 case Intrinsic::riscv_vle_mask:
893 case Intrinsic::riscv_vlse:
894 case Intrinsic::riscv_vlse_mask: {
895 bool IsMasked = IntrinID == Intrinsic::riscv_vle_mask ||
896 IntrinID == Intrinsic::riscv_vlse_mask;
897 bool IsStrided = IntrinID == Intrinsic::riscv_vlse ||
898 IntrinID == Intrinsic::riscv_vlse_mask;
899 LLT VT = MRI->
getType(
I.getOperand(0).getReg());
903 const Register DstReg =
I.getOperand(0).getReg();
906 bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
911 if (HasPassthruOperand) {
912 auto PassthruReg =
I.getOperand(CurOp++).getReg();
918 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked, IsStrided);
921 const RISCV::VLEPseudo *
P =
922 RISCV::getVLEPseudo(IsMasked, IsStrided,
false, Log2SEW,
923 static_cast<unsigned>(LMUL));
925 MachineInstrBuilder PseudoMI =
926 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(
P->Pseudo), DstReg);
931 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
932 for (
auto &RenderFn : *VLOpFn)
941 Policy =
I.getOperand(CurOp++).getImm();
951 case Intrinsic::riscv_vloxei:
952 case Intrinsic::riscv_vloxei_mask:
953 case Intrinsic::riscv_vluxei:
954 case Intrinsic::riscv_vluxei_mask: {
955 bool IsMasked = IntrinID == Intrinsic::riscv_vloxei_mask ||
956 IntrinID == Intrinsic::riscv_vluxei_mask;
957 bool IsOrdered = IntrinID == Intrinsic::riscv_vloxei ||
958 IntrinID == Intrinsic::riscv_vloxei_mask;
959 LLT VT = MRI->
getType(
I.getOperand(0).getReg());
963 const Register DstReg =
I.getOperand(0).getReg();
966 bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
971 if (HasPassthruOperand) {
972 auto PassthruReg =
I.getOperand(CurOp++).getReg();
979 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked,
true, &IndexVT);
985 if (IndexLog2EEW == 6 && !Subtarget->
is64Bit()) {
987 "values when XLEN=32");
989 const RISCV::VLX_VSXPseudo *
P = RISCV::getVLXPseudo(
990 IsMasked, IsOrdered, IndexLog2EEW,
static_cast<unsigned>(LMUL),
991 static_cast<unsigned>(IndexLMUL));
993 MachineInstrBuilder PseudoMI =
994 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(
P->Pseudo), DstReg);
999 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
1000 for (
auto &RenderFn : *VLOpFn)
1004 PseudoMI.
addImm(Log2SEW);
1009 Policy =
I.getOperand(CurOp++).getImm();
1015 I.eraseFromParent();
1019 case Intrinsic::riscv_vsm:
1020 case Intrinsic::riscv_vse:
1021 case Intrinsic::riscv_vse_mask:
1022 case Intrinsic::riscv_vsse:
1023 case Intrinsic::riscv_vsse_mask: {
1024 bool IsMasked = IntrinID == Intrinsic::riscv_vse_mask ||
1025 IntrinID == Intrinsic::riscv_vsse_mask;
1026 bool IsStrided = IntrinID == Intrinsic::riscv_vsse ||
1027 IntrinID == Intrinsic::riscv_vsse_mask;
1028 LLT VT = MRI->
getType(
I.getOperand(1).getReg());
1036 auto PassthruReg =
I.getOperand(CurOp++).getReg();
1039 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked, IsStrided);
1042 const RISCV::VSEPseudo *
P = RISCV::getVSEPseudo(
1043 IsMasked, IsStrided, Log2SEW,
static_cast<unsigned>(LMUL));
1045 MachineInstrBuilder PseudoMI =
1051 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
1052 for (
auto &RenderFn : *VLOpFn)
1056 PseudoMI.
addImm(Log2SEW);
1061 I.eraseFromParent();
1065 case Intrinsic::riscv_vsoxei:
1066 case Intrinsic::riscv_vsoxei_mask:
1067 case Intrinsic::riscv_vsuxei:
1068 case Intrinsic::riscv_vsuxei_mask: {
1069 bool IsMasked = IntrinID == Intrinsic::riscv_vsoxei_mask ||
1070 IntrinID == Intrinsic::riscv_vsuxei_mask;
1071 bool IsOrdered = IntrinID == Intrinsic::riscv_vsoxei ||
1072 IntrinID == Intrinsic::riscv_vsoxei_mask;
1073 LLT VT = MRI->
getType(
I.getOperand(1).getReg());
1081 auto PassthruReg =
I.getOperand(CurOp++).getReg();
1085 addVectorLoadStoreOperands(
I, SrcOps, CurOp, IsMasked,
true, &IndexVT);
1091 if (IndexLog2EEW == 6 && !Subtarget->
is64Bit()) {
1093 "values when XLEN=32");
1095 const RISCV::VLX_VSXPseudo *
P = RISCV::getVSXPseudo(
1096 IsMasked, IsOrdered, IndexLog2EEW,
static_cast<unsigned>(LMUL),
1097 static_cast<unsigned>(IndexLMUL));
1099 MachineInstrBuilder PseudoMI =
1105 auto VLOpFn = renderVLOp(
I.getOperand(CurOp++));
1106 for (
auto &RenderFn : *VLOpFn)
1110 PseudoMI.
addImm(Log2SEW);
1115 I.eraseFromParent();
1122bool RISCVInstructionSelector::selectIntrinsic(MachineInstr &
I)
const {
1129 case Intrinsic::riscv_vsetvli:
1130 case Intrinsic::riscv_vsetvlimax: {
1132 bool VLMax = IntrinID == Intrinsic::riscv_vsetvlimax;
1134 unsigned Offset = VLMax ? 2 : 3;
1142 Register DstReg =
I.getOperand(0).getReg();
1145 unsigned Opcode = RISCV::PseudoVSETVLI;
1149 Register AVLReg =
I.getOperand(2).getReg();
1151 uint64_t AVL = AVLConst->Value.getZExtValue();
1164 Opcode = RISCV::PseudoVSETVLIX0;
1166 Register AVLReg =
I.getOperand(2).getReg();
1171 uint64_t AVL = AVLConst->Value.getZExtValue();
1173 MachineInstr *PseudoMI =
1175 TII.get(RISCV::PseudoVSETIVLI), DstReg)
1178 I.eraseFromParent();
1185 MachineInstr *PseudoMI =
1186 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode), DstReg)
1189 I.eraseFromParent();
1196bool RISCVInstructionSelector::selectExtractSubvector(MachineInstr &
MI)
const {
1197 assert(
MI.getOpcode() == TargetOpcode::G_EXTRACT_SUBVECTOR);
1202 LLT DstTy = MRI->
getType(DstReg);
1203 LLT SrcTy = MRI->
getType(SrcReg);
1205 unsigned Idx =
static_cast<unsigned>(
MI.getOperand(2).
getImm());
1211 std::tie(SubRegIdx, Idx) =
1213 SrcMVT, DstMVT, Idx, &
TRI);
1228 BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1230 .
addReg(SrcReg, {}, SubRegIdx);
1232 MI.eraseFromParent();
1236bool RISCVInstructionSelector::selectInsertSubVector(MachineInstr &
MI)
const {
1237 assert(
MI.getOpcode() == TargetOpcode::G_INSERT_SUBVECTOR);
1241 Register SubVecReg =
MI.getOperand(2).getReg();
1243 LLT VecTy = MRI->
getType(VecReg);
1244 LLT SubVecTy = MRI->
getType(SubVecReg);
1249 unsigned Idx =
static_cast<unsigned>(
MI.getOperand(3).
getImm());
1252 std::tie(SubRegIdx, Idx) =
1254 VecMVT, SubVecMVT, Idx, &
TRI);
1270 if (SubRegIdx == RISCV::NoSubRegister) {
1273 "Unexpected subvector insert");
1274 BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1277 MI.eraseFromParent();
1283 MachineInstr *Ins =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1284 TII.get(TargetOpcode::INSERT_SUBREG), DstReg)
1289 MI.eraseFromParent();
1294bool RISCVInstructionSelector::select(MachineInstr &
MI) {
1296 const unsigned Opc =
MI.getOpcode();
1298 if (!
MI.isPreISelOpcode() ||
Opc == TargetOpcode::G_PHI) {
1299 if (
Opc == TargetOpcode::PHI ||
Opc == TargetOpcode::G_PHI) {
1300 const Register DefReg =
MI.getOperand(0).getReg();
1301 const LLT DefTy = MRI->
getType(DefReg);
1315 DefRC =
TRI.getRegClassForTypeOnBank(DefTy, RB, STI.
is64Bit());
1322 MI.setDesc(
TII.get(TargetOpcode::PHI));
1333 if (selectImpl(
MI, *CoverageInfo))
1337 case TargetOpcode::G_ANYEXT:
1338 case TargetOpcode::G_PTRTOINT:
1339 case TargetOpcode::G_INTTOPTR:
1340 case TargetOpcode::G_TRUNC:
1341 case TargetOpcode::G_FREEZE:
1343 case TargetOpcode::G_CONSTANT: {
1345 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
1347 if (!materializeImm(DstReg,
Imm,
MI))
1350 MI.eraseFromParent();
1353 case TargetOpcode::G_ZEXT:
1354 case TargetOpcode::G_SEXT: {
1355 bool IsSigned =
Opc != TargetOpcode::G_ZEXT;
1358 LLT SrcTy = MRI->
getType(SrcReg);
1365 RISCV::GPRBRegBankID &&
1366 "Unexpected ext regbank");
1369 if (IsSigned && SrcSize == 32) {
1370 MI.setDesc(
TII.get(RISCV::ADDIW));
1377 if (!IsSigned && SrcSize == 32 && STI.hasStdExtZba()) {
1378 MI.setDesc(
TII.get(RISCV::ADD_UW));
1385 if (SrcSize == 16 &&
1386 (STI.hasStdExtZbb() || (!IsSigned && STI.hasStdExtZbkb()))) {
1387 MI.setDesc(
TII.get(IsSigned ? RISCV::SEXT_H
1388 : STI.
is64Bit() ? RISCV::ZEXT_H_RV64
1389 : RISCV::ZEXT_H_RV32));
1396 MachineInstr *ShiftLeft =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1397 TII.get(RISCV::SLLI), ShiftLeftReg)
1401 MachineInstr *ShiftRight =
1403 TII.get(IsSigned ? RISCV::SRAI : RISCV::SRLI), DstReg)
1407 MI.eraseFromParent();
1410 case TargetOpcode::G_FCONSTANT: {
1413 const APFloat &FPimm =
MI.getOperand(1).getFPImm()->getValueAPF();
1422 if (!materializeImm(GPRReg,
Imm.getSExtValue(),
MI))
1426 unsigned Opcode =
Size == 64 ? RISCV::FMV_D_X
1427 :
Size == 32 ? RISCV::FMV_W_X
1429 MachineInstr *FMV =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1430 TII.get(Opcode), DstReg)
1436 "Unexpected size or subtarget");
1440 MachineInstr *FCVT =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1441 TII.get(RISCV::FCVT_D_W), DstReg)
1446 MI.eraseFromParent();
1454 if (!materializeImm(GPRRegHigh,
Imm.extractBits(32, 32).getSExtValue(),
1457 if (!materializeImm(GPRRegLow,
Imm.trunc(32).getSExtValue(),
MI))
1459 MachineInstr *PairF64 =
1461 TII.get(RISCV::BuildPairF64Pseudo), DstReg)
1467 MI.eraseFromParent();
1470 case TargetOpcode::G_GLOBAL_VALUE: {
1471 auto *GV =
MI.getOperand(1).getGlobal();
1472 if (GV->isThreadLocal()) {
1477 return selectAddr(
MI, GV->isDSOLocal(), GV->hasExternalWeakLinkage());
1479 case TargetOpcode::G_JUMP_TABLE:
1480 case TargetOpcode::G_CONSTANT_POOL:
1481 return selectAddr(
MI);
1482 case TargetOpcode::G_BRCOND: {
1487 MachineInstr *Bcc =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1491 .
addMBB(
MI.getOperand(1).getMBB());
1492 MI.eraseFromParent();
1496 case TargetOpcode::G_SELECT:
1497 return selectSelect(
MI);
1498 case TargetOpcode::G_FCMP:
1499 return selectFPCompare(
MI);
1500 case TargetOpcode::G_FENCE: {
1505 emitFence(FenceOrdering, FenceSSID,
MI);
1506 MI.eraseFromParent();
1509 case TargetOpcode::G_IMPLICIT_DEF:
1510 return selectImplicitDef(
MI);
1511 case TargetOpcode::G_UNMERGE_VALUES:
1513 case TargetOpcode::G_LOAD:
1514 case TargetOpcode::G_STORE: {
1518 LLT PtrTy = MRI->
getType(PtrReg);
1520 const RegisterBank &RB = *RBI.
getRegBank(ValReg, *MRI,
TRI);
1521 if (RB.
getID() != RISCV::GPRBRegBankID)
1525 const RegisterBank &PtrRB = *RBI.
getRegBank(PtrReg, *MRI,
TRI);
1528 "Load/Store pointer operand isn't a GPR");
1529 assert(PtrTy.
isPointer() &&
"Load/Store pointer operand isn't a pointer");
1546 if (NewOpc ==
MI.getOpcode())
1550 auto AddrModeFns = selectAddrRegImm(
MI.getOperand(1));
1555 MachineInstrBuilder NewInst =
1563 for (
auto &Fn : *AddrModeFns)
1565 MI.eraseFromParent();
1570 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
1571 return selectIntrinsicWithSideEffects(
MI);
1572 case TargetOpcode::G_INTRINSIC:
1573 return selectIntrinsic(
MI);
1574 case TargetOpcode::G_EXTRACT_SUBVECTOR:
1575 return selectExtractSubvector(
MI);
1576 case TargetOpcode::G_INSERT_SUBVECTOR:
1577 return selectInsertSubVector(
MI);
1583bool RISCVInstructionSelector::selectUnmergeValues(MachineInstr &
MI)
const {
1584 assert(
MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
1586 if (!Subtarget->hasStdExtZfa())
1590 if (
MI.getNumOperands() != 3)
1595 if (!isRegInFprb(Src) || !isRegInGprb(
Lo) || !isRegInGprb(
Hi))
1598 MachineInstr *ExtractLo =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1599 TII.get(RISCV::FMV_X_W_FPR64),
Lo)
1603 MachineInstr *ExtractHi =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1604 TII.get(RISCV::FMVH_X_D),
Hi)
1608 MI.eraseFromParent();
1612bool RISCVInstructionSelector::replacePtrWithInt(MachineInstr &
MI,
1614 MachineOperand &
Op =
MI.getOperand(OpIdx);
1621 MachineInstr *PtrToInt =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1622 TII.get(TargetOpcode::G_PTRTOINT), IntReg)
1625 return select(*PtrToInt);
1628void RISCVInstructionSelector::preISelLower(MachineInstr &
MI) {
1629 switch (
MI.getOpcode()) {
1630 case TargetOpcode::G_PTR_ADD: {
1634 replacePtrWithInt(
MI, 1);
1635 MI.setDesc(
TII.get(TargetOpcode::G_ADD));
1639 case TargetOpcode::G_PTRMASK: {
1642 replacePtrWithInt(
MI, 1);
1643 MI.setDesc(
TII.get(TargetOpcode::G_AND));
1650void RISCVInstructionSelector::renderNegImm(MachineInstrBuilder &MIB,
1651 const MachineInstr &
MI,
1653 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1654 "Expected G_CONSTANT");
1655 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
1659void RISCVInstructionSelector::renderImmSubFromXLen(MachineInstrBuilder &MIB,
1660 const MachineInstr &
MI,
1662 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1663 "Expected G_CONSTANT");
1664 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
1668void RISCVInstructionSelector::renderImmSubFrom32(MachineInstrBuilder &MIB,
1669 const MachineInstr &
MI,
1671 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1672 "Expected G_CONSTANT");
1673 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
1677void RISCVInstructionSelector::renderImmPlus1(MachineInstrBuilder &MIB,
1678 const MachineInstr &
MI,
1680 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1681 "Expected G_CONSTANT");
1682 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
1686void RISCVInstructionSelector::renderTrailingZeros(MachineInstrBuilder &MIB,
1687 const MachineInstr &
MI,
1689 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1690 "Expected G_CONSTANT");
1691 uint64_t C =
MI.getOperand(1).getCImm()->getZExtValue();
1695void RISCVInstructionSelector::renderXLenSubTrailingOnes(
1696 MachineInstrBuilder &MIB,
const MachineInstr &
MI,
int OpIdx)
const {
1697 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1698 "Expected G_CONSTANT");
1699 uint64_t C =
MI.getOperand(1).getCImm()->getZExtValue();
1703void RISCVInstructionSelector::renderAddiPairImmSmall(MachineInstrBuilder &MIB,
1704 const MachineInstr &
MI,
1706 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1707 "Expected G_CONSTANT");
1708 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
1709 int64_t Adj =
Imm < 0 ? -2048 : 2047;
1713void RISCVInstructionSelector::renderAddiPairImmLarge(MachineInstrBuilder &MIB,
1714 const MachineInstr &
MI,
1716 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1717 "Expected G_CONSTANT");
1718 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue() < 0 ? -2048 : 2047;
1722bool RISCVInstructionSelector::isRegInGprb(
Register Reg)
const {
1726bool RISCVInstructionSelector::isRegInFprb(
Register Reg)
const {
1734bool RISCVInstructionSelector::isWorthFoldingAdd(
Register AddResult)
const {
1745 LLT Ty = MRI->
getType(
User.getOperand(0).getReg());
1752bool RISCVInstructionSelector::selectCopy(MachineInstr &
MI)
const {
1759 TRI.getConstrainedRegClassForReg(DstReg, *MRI);
1762 "Register class not available for LLT, register bank combination");
1773 MI.setDesc(
TII.get(RISCV::COPY));
1777bool RISCVInstructionSelector::selectImplicitDef(MachineInstr &
MI)
const {
1778 assert(
MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
1780 const Register DstReg =
MI.getOperand(0).getReg();
1785 "Register class not available for LLT, register bank combination");
1791 MI.setDesc(
TII.get(TargetOpcode::IMPLICIT_DEF));
1795bool RISCVInstructionSelector::materializeImm(
Register DstReg, int64_t
Imm,
1796 MachineInstr &
MI)
const {
1806 return materializeInstSeq(DstReg, Seq,
MI);
1809bool RISCVInstructionSelector::materializeInstSeq(
1811 assert(!Seq.
empty() &&
"materializeInstSeq requires a non-empty sequence");
1815 unsigned NumInsts = Seq.
size();
1818 for (
unsigned i = 0; i < NumInsts; i++) {
1822 const RISCVMatInt::Inst &
I = Seq[i];
1825 switch (
I.getOpndKind()) {
1855InstructionSelector::ComplexRendererFns
1856RISCVInstructionSelector::computeConstAddr(int64_t CVal,
bool IsPrefetch,
1863 auto emit = [&](ConstAddrPlan Plan) -> ComplexRendererFns {
1864 return {{[=](MachineInstrBuilder &MIB) {
1865 MIB.
addReg(materializeConstBase(MIB, Plan, OrigBase));
1867 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Plan.Lo12); }}};
1870 if (IsPrefetch && (Lo12 & 0b11111) != 0)
1871 return std::nullopt;
1875 Plan.Kind = ConstAddrPlan::LUI;
1876 Plan.Hi20 = (
Hi >> 12) & 0xfffff;
1878 return emit(std::move(Plan));
1884 if (Seq.
back().getOpcode() != RISCV::ADDI)
1885 return std::nullopt;
1886 Lo12 = Seq.
back().getImm();
1887 if (IsPrefetch && (Lo12 & 0b11111) != 0)
1888 return std::nullopt;
1891 return std::nullopt;
1893 Plan.Kind = ConstAddrPlan::InstSeq;
1894 Plan.Seq = std::move(Seq);
1896 return emit(std::move(Plan));
1900RISCVInstructionSelector::materializeConstBase(MachineInstrBuilder &MIB,
1901 const ConstAddrPlan &Plan,
1905 MachineInstr &InsertPt = *MIB.
getInstr();
1908 switch (Plan.Kind) {
1909 case ConstAddrPlan::X0:
1911 case ConstAddrPlan::LUI: {
1913 MachineInstr *LUI =
BuildMI(
MBB, InsertPt,
DL,
TII.get(RISCV::LUI), HiReg)
1918 case ConstAddrPlan::InstSeq: {
1920 materializeInstSeq(HiReg, Plan.Seq, InsertPt);
1927 if (OrigBase.
isValid() && HiReg != RISCV::X0) {
1935 return OrigBase.
isValid() ? OrigBase : HiReg;
1938bool RISCVInstructionSelector::selectAddr(MachineInstr &
MI,
bool IsLocal,
1939 bool IsExternWeak)
const {
1940 assert((
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
1941 MI.getOpcode() == TargetOpcode::G_JUMP_TABLE ||
1942 MI.getOpcode() == TargetOpcode::G_CONSTANT_POOL) &&
1943 "Unexpected opcode");
1945 const MachineOperand &DispMO =
MI.getOperand(1);
1948 const LLT DefTy = MRI->
getType(DefReg);
1955 if (IsLocal && !Subtarget->allowTaggedGlobals()) {
1959 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1976 TII.get(RISCV::PseudoLGA), DefReg)
1982 MI.eraseFromParent();
1989 "Unsupported code model for lowering",
MI);
1997 MachineInstr *AddrHi =
BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(),
1998 TII.get(RISCV::LUI), AddrHiDest)
2004 TII.get(RISCV::ADDI), DefReg)
2010 MI.eraseFromParent();
2031 TII.get(RISCV::PseudoLGA), DefReg)
2037 MI.eraseFromParent();
2044 MI.setDesc(
TII.get(RISCV::PseudoLLA));
2052bool RISCVInstructionSelector::selectSelect(MachineInstr &
MI)
const {
2059 Register DstReg = SelectMI.getReg(0);
2061 unsigned Opc = RISCV::Select_GPR_Using_CC_GPR;
2064 Opc =
Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR
2065 : RISCV::Select_FPR64_Using_CC_GPR;
2074 .
addReg(SelectMI.getTrueReg())
2075 .
addReg(SelectMI.getFalseReg());
2076 MI.eraseFromParent();
2088 return Size == 16 ? RISCV::FLT_H :
Size == 32 ? RISCV::FLT_S : RISCV::FLT_D;
2090 return Size == 16 ? RISCV::FLE_H :
Size == 32 ? RISCV::FLE_S : RISCV::FLE_D;
2092 return Size == 16 ? RISCV::FEQ_H :
Size == 32 ? RISCV::FEQ_S : RISCV::FEQ_D;
2105 assert(!isLegalFCmpPredicate(Pred) &&
"Predicate already legal?");
2108 if (isLegalFCmpPredicate(InvPred)) {
2116 if (isLegalFCmpPredicate(InvPred)) {
2121 if (isLegalFCmpPredicate(InvPred)) {
2133bool RISCVInstructionSelector::selectFPCompare(MachineInstr &
MI)
const {
2146 bool NeedInvert =
false;
2160 MachineInstr *Cmp1 =
2167 MachineInstr *Cmp2 =
2176 TII.get(RISCV::OR), TmpReg)
2195 MachineInstr *Cmp1 =
2202 MachineInstr *Cmp2 =
2209 TII.get(RISCV::AND), TmpReg)
2220 TII.get(RISCV::XORI), DstReg)
2226 MI.eraseFromParent();
2230void RISCVInstructionSelector::emitFence(
AtomicOrdering FenceOrdering,
2232 MachineInstr &
MI)
const {
2236 if (STI.hasStdExtZtso()) {
2239 if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
2263 unsigned Pred, Succ;
2264 switch (FenceOrdering) {
2267 case AtomicOrdering::AcquireRelease:
2271 case AtomicOrdering::Acquire:
2276 case AtomicOrdering::Release:
2281 case AtomicOrdering::SequentiallyConsistent:
2291InstructionSelector *
2295 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.