25#include "llvm/IR/IntrinsicsRISCV.h"
28#define DEBUG_TYPE "riscv-isel"
31using namespace MIPatternMatch;
33#define GET_GLOBALISEL_PREDICATE_BITSET
34#include "RISCVGenGlobalISel.inc"
35#undef GET_GLOBALISEL_PREDICATE_BITSET
60 static constexpr unsigned MaxRecursionDepth = 6;
63 const unsigned Depth = 0)
const;
71 bool isRegInGprb(
Register Reg)
const;
72 bool isRegInFprb(
Register Reg)
const;
89 bool IsExternWeak =
false)
const;
97 unsigned ShiftWidth)
const;
98 ComplexRendererFns selectShiftMaskXLen(
MachineOperand &Root)
const {
99 return selectShiftMask(Root, STI.
getXLen());
101 ComplexRendererFns selectShiftMask32(
MachineOperand &Root)
const {
102 return selectShiftMask(Root, 32);
106 ComplexRendererFns selectSExtBits(
MachineOperand &Root,
unsigned Bits)
const;
107 template <
unsigned Bits>
109 return selectSExtBits(Root, Bits);
112 ComplexRendererFns selectZExtBits(
MachineOperand &Root,
unsigned Bits)
const;
113 template <
unsigned Bits>
115 return selectZExtBits(Root, Bits);
118 ComplexRendererFns selectSHXADDOp(
MachineOperand &Root,
unsigned ShAmt)
const;
119 template <
unsigned ShAmt>
121 return selectSHXADDOp(Root, ShAmt);
125 unsigned ShAmt)
const;
126 template <
unsigned ShAmt>
127 ComplexRendererFns selectSHXADD_UWOp(
MachineOperand &Root)
const {
128 return selectSHXADD_UWOp(Root, ShAmt);
168#define GET_GLOBALISEL_PREDICATES_DECL
169#include "RISCVGenGlobalISel.inc"
170#undef GET_GLOBALISEL_PREDICATES_DECL
172#define GET_GLOBALISEL_TEMPORARIES_DECL
173#include "RISCVGenGlobalISel.inc"
174#undef GET_GLOBALISEL_TEMPORARIES_DECL
179#define GET_GLOBALISEL_IMPL
180#include "RISCVGenGlobalISel.inc"
181#undef GET_GLOBALISEL_IMPL
183RISCVInstructionSelector::RISCVInstructionSelector(
186 : STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()), RBI(RBI),
190#include
"RISCVGenGlobalISel.inc"
193#include
"RISCVGenGlobalISel.inc"
199bool RISCVInstructionSelector::hasAllNBitUsers(
const MachineInstr &
MI,
201 const unsigned Depth)
const {
203 assert((
MI.getOpcode() == TargetOpcode::G_ADD ||
204 MI.getOpcode() == TargetOpcode::G_SUB ||
205 MI.getOpcode() == TargetOpcode::G_MUL ||
206 MI.getOpcode() == TargetOpcode::G_SHL ||
207 MI.getOpcode() == TargetOpcode::G_LSHR ||
208 MI.getOpcode() == TargetOpcode::G_AND ||
209 MI.getOpcode() == TargetOpcode::G_OR ||
210 MI.getOpcode() == TargetOpcode::G_XOR ||
211 MI.getOpcode() == TargetOpcode::G_SEXT_INREG ||
Depth != 0) &&
212 "Unexpected opcode");
214 if (
Depth >= RISCVInstructionSelector::MaxRecursionDepth)
217 auto DestReg =
MI.getOperand(0).getReg();
218 for (
auto &UserOp :
MRI->use_nodbg_operands(DestReg)) {
219 assert(UserOp.getParent() &&
"UserOp must have a parent");
236 if (
OpIdx == 2 && Bits >=
Log2_32(Subtarget->getXLen()))
245 if (Bits >= (
unsigned)llvm::bit_width<uint64_t>(
273 unsigned ShiftWidth)
const {
283 ShAmtReg = ZExtSrcReg;
303 if (ShMask.isSubsetOf(AndMask)) {
304 ShAmtReg = AndSrcReg;
308 KnownBits Known = VT->getKnownBits(AndSrcReg);
309 if (ShMask.isSubsetOf(AndMask | Known.
Zero))
310 ShAmtReg = AndSrcReg;
317 if (Imm != 0 &&
Imm.urem(ShiftWidth) == 0)
322 if (Imm != 0 &&
Imm.urem(ShiftWidth) == 0) {
325 ShAmtReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
326 unsigned NegOpc = Subtarget->is64Bit() ? RISCV::SUBW : RISCV::SUB;
333 if (
Imm.urem(ShiftWidth) == ShiftWidth - 1) {
336 ShAmtReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
351 unsigned Bits)
const {
357 if (RootDef->
getOpcode() == TargetOpcode::G_SEXT_INREG &&
363 unsigned Size =
MRI->getType(RootReg).getScalarSizeInBits();
364 if ((
Size - VT->computeNumSignBits(RootReg)) <
Bits)
372 unsigned Bits)
const {
384 MRI->getType(RegX).getScalarSizeInBits() ==
Bits)
387 unsigned Size =
MRI->getType(RootReg).getScalarSizeInBits();
396 unsigned ShAmt)
const {
403 const unsigned XLen = STI.getXLen();
422 if (
Mask.isShiftedMask()) {
423 unsigned Leading = XLen -
Mask.getActiveBits();
424 unsigned Trailing =
Mask.countr_zero();
427 if (*LeftShift && Leading == 0 && C2.
ult(Trailing) && Trailing == ShAmt) {
428 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
439 if (!*LeftShift && Leading == C2 && Trailing == ShAmt) {
440 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
444 .addImm(Leading + Trailing);
465 unsigned Leading = XLen -
Mask.getActiveBits();
466 unsigned Trailing =
Mask.countr_zero();
479 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
494 unsigned ShAmt)
const {
512 if (
Mask.isShiftedMask()) {
513 unsigned Leading =
Mask.countl_zero();
514 unsigned Trailing =
Mask.countr_zero();
515 if (Leading == 32 - ShAmt && C2 == Trailing && Trailing > ShAmt) {
516 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
532 assert(Root.
isReg() &&
"Expected operand to be a Register");
535 if (RootDef->
getOpcode() == TargetOpcode::G_CONSTANT) {
537 if (
C->getValue().isAllOnes())
545 if (isUInt<5>(
C->getZExtValue())) {
554RISCVInstructionSelector::selectAddrRegImm(
MachineOperand &Root)
const {
559 if (RootDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX) {
566 if (isBaseWithConstantOffset(Root, *
MRI)) {
573 if (isInt<12>(RHSC)) {
574 if (LHSDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX)
597 case CmpInst::Predicate::ICMP_EQ:
599 case CmpInst::Predicate::ICMP_NE:
601 case CmpInst::Predicate::ICMP_ULT:
603 case CmpInst::Predicate::ICMP_SLT:
605 case CmpInst::Predicate::ICMP_UGE:
607 case CmpInst::Predicate::ICMP_SGE:
629 case CmpInst::Predicate::ICMP_SGT:
637 case CmpInst::Predicate::ICMP_SLT:
654 case CmpInst::Predicate::ICMP_EQ:
655 case CmpInst::Predicate::ICMP_NE:
656 case CmpInst::Predicate::ICMP_ULT:
657 case CmpInst::Predicate::ICMP_SLT:
658 case CmpInst::Predicate::ICMP_UGE:
659 case CmpInst::Predicate::ICMP_SGE:
662 case CmpInst::Predicate::ICMP_SGT:
663 case CmpInst::Predicate::ICMP_SLE:
664 case CmpInst::Predicate::ICMP_UGT:
665 case CmpInst::Predicate::ICMP_ULE:
673 CC = getRISCVCCFromICmp(Pred);
679 preISelLower(
MI, MIB);
680 const unsigned Opc =
MI.getOpcode();
682 if (!
MI.isPreISelOpcode() ||
Opc == TargetOpcode::G_PHI) {
683 if (
Opc == TargetOpcode::PHI ||
Opc == TargetOpcode::G_PHI) {
684 const Register DefReg =
MI.getOperand(0).getReg();
685 const LLT DefTy =
MRI->getType(DefReg);
688 MRI->getRegClassOrRegBank(DefReg);
691 dyn_cast<const TargetRegisterClass *>(RegClassOrBank);
698 const RegisterBank &RB = *cast<const RegisterBank *>(RegClassOrBank);
699 DefRC = getRegClassForTypeOnBank(DefTy, RB);
706 MI.setDesc(
TII.get(TargetOpcode::PHI));
707 return RBI.constrainGenericRegister(DefReg, *DefRC, *
MRI);
717 if (selectImpl(
MI, *CoverageInfo))
721 case TargetOpcode::G_ANYEXT:
722 case TargetOpcode::G_PTRTOINT:
723 case TargetOpcode::G_INTTOPTR:
724 case TargetOpcode::G_TRUNC:
725 case TargetOpcode::G_FREEZE:
727 case TargetOpcode::G_CONSTANT: {
729 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
731 if (!materializeImm(DstReg, Imm, MIB))
734 MI.eraseFromParent();
737 case TargetOpcode::G_FCONSTANT: {
740 const APFloat &FPimm =
MI.getOperand(1).getFPImm()->getValueAPF();
742 unsigned Size =
MRI->getType(DstReg).getSizeInBits();
743 if (
Size == 16 ||
Size == 32 || (
Size == 64 && Subtarget->is64Bit())) {
744 Register GPRReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
745 if (!materializeImm(GPRReg,
Imm.getSExtValue(), MIB))
748 unsigned Opcode =
Size == 64 ? RISCV::FMV_D_X
749 :
Size == 32 ? RISCV::FMV_W_X
751 auto FMV = MIB.buildInstr(Opcode, {DstReg}, {GPRReg});
752 if (!FMV.constrainAllUses(
TII,
TRI, RBI))
757 "Unexpected size or subtarget");
759 if (
Imm.isNonNegative() &&
Imm.isZero()) {
762 MIB.buildInstr(RISCV::FCVT_D_W, {DstReg}, {
Register(RISCV::X0)})
767 MI.eraseFromParent();
772 Register GPRRegHigh =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
773 Register GPRRegLow =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
774 if (!materializeImm(GPRRegHigh,
Imm.extractBits(32, 32).getSExtValue(),
777 if (!materializeImm(GPRRegLow,
Imm.trunc(32).getSExtValue(), MIB))
780 RISCV::BuildPairF64Pseudo, {DstReg}, {GPRRegLow, GPRRegHigh});
785 MI.eraseFromParent();
788 case TargetOpcode::G_GLOBAL_VALUE: {
789 auto *GV =
MI.getOperand(1).getGlobal();
790 if (GV->isThreadLocal()) {
795 return selectAddr(
MI, MIB, GV->isDSOLocal(), GV->hasExternalWeakLinkage());
797 case TargetOpcode::G_JUMP_TABLE:
798 case TargetOpcode::G_CONSTANT_POOL:
799 return selectAddr(
MI, MIB,
MRI);
800 case TargetOpcode::G_BRCOND: {
806 .addMBB(
MI.getOperand(1).getMBB());
807 MI.eraseFromParent();
810 case TargetOpcode::G_BRINDIRECT:
811 MI.setDesc(
TII.get(RISCV::PseudoBRIND));
814 case TargetOpcode::G_SELECT:
815 return selectSelect(
MI, MIB);
816 case TargetOpcode::G_FCMP:
817 return selectFPCompare(
MI, MIB);
818 case TargetOpcode::G_FENCE: {
823 emitFence(FenceOrdering, FenceSSID, MIB);
824 MI.eraseFromParent();
827 case TargetOpcode::G_IMPLICIT_DEF:
828 return selectImplicitDef(
MI, MIB);
829 case TargetOpcode::G_UNMERGE_VALUES:
836bool RISCVInstructionSelector::selectUnmergeValues(
838 assert(
MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
840 if (!Subtarget->hasStdExtZfa())
844 if (
MI.getNumOperands() != 3)
849 if (!isRegInFprb(Src) || !isRegInGprb(
Lo) || !isRegInGprb(
Hi))
860 MI.eraseFromParent();
867 assert(
MRI->getType(PtrReg).isPointer() &&
"Operand is not a pointer!");
871 MRI->setRegBank(PtrToInt.getReg(0), RBI.getRegBank(RISCV::GPRBRegBankID));
872 Op.setReg(PtrToInt.getReg(0));
873 return select(*PtrToInt);
878 switch (
MI.getOpcode()) {
879 case TargetOpcode::G_PTR_ADD: {
883 replacePtrWithInt(
MI.getOperand(1), MIB);
884 MI.setDesc(
TII.get(TargetOpcode::G_ADD));
885 MRI->setType(DstReg, sXLen);
888 case TargetOpcode::G_PTRMASK: {
891 replacePtrWithInt(
MI.getOperand(1), MIB);
892 MI.setDesc(
TII.get(TargetOpcode::G_AND));
893 MRI->setType(DstReg, sXLen);
902 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
903 "Expected G_CONSTANT");
904 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
911 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
912 "Expected G_CONSTANT");
913 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
914 MIB.
addImm(STI.getXLen() - CstVal);
920 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
921 "Expected G_CONSTANT");
922 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
929 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
930 "Expected G_CONSTANT");
931 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
938 assert(
MI.getOpcode() == TargetOpcode::G_FRAME_INDEX &&
OpIdx == -1 &&
939 "Expected G_FRAME_INDEX");
940 MIB.
add(
MI.getOperand(1));
946 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
947 "Expected G_CONSTANT");
948 uint64_t C =
MI.getOperand(1).getCImm()->getZExtValue();
952void RISCVInstructionSelector::renderXLenSubTrailingOnes(
954 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
955 "Expected G_CONSTANT");
956 uint64_t C =
MI.getOperand(1).getCImm()->getZExtValue();
963 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
964 "Expected G_CONSTANT");
965 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
966 int64_t Adj =
Imm < 0 ? -2048 : 2047;
973 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT &&
OpIdx == -1 &&
974 "Expected G_CONSTANT");
975 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue() < 0 ? -2048 : 2047;
981 if (RB.
getID() == RISCV::GPRBRegBankID) {
983 return &RISCV::GPRRegClass;
986 if (RB.
getID() == RISCV::FPRBRegBankID) {
988 return &RISCV::FPR16RegClass;
990 return &RISCV::FPR32RegClass;
992 return &RISCV::FPR64RegClass;
995 if (RB.
getID() == RISCV::VRBRegBankID) {
997 return &RISCV::VRRegClass;
1000 return &RISCV::VRM2RegClass;
1003 return &RISCV::VRM4RegClass;
1006 return &RISCV::VRM8RegClass;
1012bool RISCVInstructionSelector::isRegInGprb(
Register Reg)
const {
1013 return RBI.getRegBank(Reg, *
MRI,
TRI)->
getID() == RISCV::GPRBRegBankID;
1016bool RISCVInstructionSelector::isRegInFprb(
Register Reg)
const {
1017 return RBI.getRegBank(Reg, *
MRI,
TRI)->getID() == RISCV::FPRBRegBankID;
1020bool RISCVInstructionSelector::selectCopy(
MachineInstr &
MI)
const {
1027 MRI->getType(DstReg), *RBI.getRegBank(DstReg, *
MRI,
TRI));
1029 "Register class not available for LLT, register bank combination");
1034 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *
MRI)) {
1040 MI.setDesc(
TII.get(RISCV::COPY));
1044bool RISCVInstructionSelector::selectImplicitDef(
MachineInstr &
MI,
1046 assert(
MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
1048 const Register DstReg =
MI.getOperand(0).getReg();
1050 MRI->getType(DstReg), *RBI.getRegBank(DstReg, *
MRI,
TRI));
1053 "Register class not available for LLT, register bank combination");
1055 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *
MRI)) {
1059 MI.setDesc(
TII.get(TargetOpcode::IMPLICIT_DEF));
1063bool RISCVInstructionSelector::materializeImm(
Register DstReg, int64_t Imm,
1067 RBI.constrainGenericRegister(DstReg, RISCV::GPRRegClass, *
MRI);
1072 unsigned NumInsts = Seq.
size();
1075 for (
unsigned i = 0; i < NumInsts; i++) {
1077 ?
MRI->createVirtualRegister(&RISCV::GPRRegClass)
1082 switch (
I.getOpndKind()) {
1091 {SrcReg, Register(RISCV::X0)});
1113 bool IsExternWeak)
const {
1114 assert((
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
1115 MI.getOpcode() == TargetOpcode::G_JUMP_TABLE ||
1116 MI.getOpcode() == TargetOpcode::G_CONSTANT_POOL) &&
1117 "Unexpected opcode");
1122 const LLT DefTy =
MRI->getType(DefReg);
1128 if (
TM.isPositionIndependent() || Subtarget->allowTaggedGlobals()) {
1129 if (IsLocal && !Subtarget->allowTaggedGlobals()) {
1133 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1155 MI.eraseFromParent();
1159 switch (
TM.getCodeModel()) {
1162 getName(),
"Unsupported code model for lowering",
MI);
1169 Register AddrHiDest =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1182 MI.eraseFromParent();
1209 MI.eraseFromParent();
1216 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1225 auto &SelectMI = cast<GSelect>(
MI);
1231 Register DstReg = SelectMI.getReg(0);
1233 unsigned Opc = RISCV::Select_GPR_Using_CC_GPR;
1234 if (RBI.getRegBank(DstReg, *
MRI,
TRI)->getID() == RISCV::FPRBRegBankID) {
1235 unsigned Size =
MRI->getType(DstReg).getSizeInBits();
1236 Opc =
Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR
1237 : RISCV::Select_FPR64_Using_CC_GPR;
1245 .
addReg(SelectMI.getTrueReg())
1246 .
addReg(SelectMI.getFalseReg());
1247 MI.eraseFromParent();
1258 return Size == 16 ? RISCV::FLT_H :
Size == 32 ? RISCV::FLT_S : RISCV::FLT_D;
1260 return Size == 16 ? RISCV::FLE_H :
Size == 32 ? RISCV::FLE_S : RISCV::FLE_D;
1262 return Size == 16 ? RISCV::FEQ_H :
Size == 32 ? RISCV::FEQ_S : RISCV::FEQ_D;
1275 assert(!isLegalFCmpPredicate(Pred) &&
"Predicate already legal?");
1278 if (isLegalFCmpPredicate(InvPred)) {
1286 if (isLegalFCmpPredicate(InvPred)) {
1291 if (isLegalFCmpPredicate(InvPred)) {
1305 auto &CmpMI = cast<GFCmp>(
MI);
1312 unsigned Size =
MRI->getType(LHS).getSizeInBits();
1317 bool NeedInvert =
false;
1321 TmpReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1323 if (!
Cmp.constrainAllUses(
TII,
TRI, RBI))
1329 {&RISCV::GPRRegClass}, {
LHS,
RHS});
1330 if (!Cmp1.constrainAllUses(
TII,
TRI, RBI))
1333 {&RISCV::GPRRegClass}, {
RHS,
LHS});
1334 if (!Cmp2.constrainAllUses(
TII,
TRI, RBI))
1337 TmpReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1339 MIB.
buildInstr(RISCV::OR, {TmpReg}, {Cmp1.getReg(0), Cmp2.getReg(0)});
1340 if (!
Or.constrainAllUses(
TII,
TRI, RBI))
1347 {&RISCV::GPRRegClass}, {
LHS,
LHS});
1348 if (!Cmp1.constrainAllUses(
TII,
TRI, RBI))
1351 {&RISCV::GPRRegClass}, {
RHS,
RHS});
1352 if (!Cmp2.constrainAllUses(
TII,
TRI, RBI))
1355 TmpReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1357 MIB.
buildInstr(RISCV::AND, {TmpReg}, {Cmp1.getReg(0), Cmp2.getReg(0)});
1358 if (!
And.constrainAllUses(
TII,
TRI, RBI))
1365 auto Xor = MIB.
buildInstr(RISCV::XORI, {DstReg}, {TmpReg}).addImm(1);
1366 if (!
Xor.constrainAllUses(
TII,
TRI, RBI))
1370 MI.eraseFromParent();
1374void RISCVInstructionSelector::emitFence(
AtomicOrdering FenceOrdering,
1377 if (STI.hasStdExtZtso()) {
1380 if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
1390 MIB.
buildInstr(TargetOpcode::MEMBARRIER, {}, {});
1398 MIB.
buildInstr(TargetOpcode::MEMBARRIER, {}, {});
1404 unsigned Pred, Succ;
1405 switch (FenceOrdering) {
1408 case AtomicOrdering::AcquireRelease:
1412 case AtomicOrdering::Acquire:
1417 case AtomicOrdering::Release:
1422 case AtomicOrdering::SequentiallyConsistent:
1436 return new RISCVInstructionSelector(TM, Subtarget, RBI);
unsigned const MachineRegisterInfo * MRI
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)
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
MachineInstr unsigned OpIdx
static StringRef getName(Value *V)
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
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.
support::ulittle16_t & Lo
support::ulittle16_t & Hi
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
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
@ FCMP_OLT
0 1 0 0 True if ordered and less 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
@ 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)
@ 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.
This class represents an Operation in the Expression.
std::optional< SmallVector< std::function< void(MachineInstrBuilder &)>, 4 > > ComplexRendererFns
virtual void setupMF(MachineFunction &mf, GISelValueTracking *vt, CodeGenCoverage *covinfo=nullptr, ProfileSummaryInfo *psi=nullptr, BlockFrequencyInfo *bfi=nullptr)
Setup per-MF executor state.
virtual bool select(MachineInstr &I)=0
Select the (possibly generic) instruction I to only use target-specific opcodes.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr bool isValid() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Helper class to build MachineInstr.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
MachineInstrBuilder buildPtrToInt(const DstOp &Dst, const SrcOp &Src)
Build and insert a G_PTRTOINT instruction.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
bool constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
unsigned getOperandNo(const_mop_iterator I) const
Returns the number of the operand iterator I points to.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
@ 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).
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.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Analysis providing profile information.
This class provides the information for the target register banks.
This class implements the register bank concept.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
unsigned getID() const
Return the register class ID number.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
operand_type_match m_Reg()
operand_type_match m_Pred()
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
ConstantMatch< APInt > m_ICst(APInt &Cst)
BinaryOp_match< LHS, RHS, TargetOpcode::G_ADD, true > m_GAdd(const LHS &L, const RHS &R)
OneNonDBGUse_match< SubPat > m_OneNonDBGUse(const SubPat &SP)
CompareOp_match< Pred, LHS, RHS, TargetOpcode::G_ICMP > m_GICmp(const Pred &P, const LHS &L, const RHS &R)
SpecificConstantMatch m_SpecificICst(APInt RequestedValue)
Matches a constant equal to RequestedValue.
BinaryOp_match< LHS, RHS, TargetOpcode::G_SUB > m_GSub(const LHS &L, const RHS &R)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SHL, false > m_GShl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_AND, true > m_GAnd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_LSHR, false > m_GLShr(const LHS &L, const RHS &R)
unsigned getBrCond(CondCode CC, unsigned SelectOpc=0)
InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI)
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.
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
LLVM_ABI bool 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...
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.
LLVM_ABI void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel error as a missed optimization remark to the LLVMContext's diagnostic stream.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Xor
Bitwise or logical XOR of integers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.