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 bool isRegInGprb(
Register Reg)
const;
61 bool isRegInFprb(
Register Reg)
const;
78 bool IsExternWeak =
false)
const;
87 unsigned ShiftWidth)
const;
88 ComplexRendererFns selectShiftMaskXLen(
MachineOperand &Root)
const {
89 return selectShiftMask(Root, STI.
getXLen());
92 return selectShiftMask(Root, 32);
96 ComplexRendererFns selectSExtBits(
MachineOperand &Root,
unsigned Bits)
const;
97 template <
unsigned Bits>
99 return selectSExtBits(Root, Bits);
102 ComplexRendererFns selectZExtBits(
MachineOperand &Root,
unsigned Bits)
const;
103 template <
unsigned Bits>
105 return selectZExtBits(Root, Bits);
108 ComplexRendererFns selectSHXADDOp(
MachineOperand &Root,
unsigned ShAmt)
const;
109 template <
unsigned ShAmt>
111 return selectSHXADDOp(Root, ShAmt);
115 unsigned ShAmt)
const;
116 template <
unsigned ShAmt>
117 ComplexRendererFns selectSHXADD_UWOp(
MachineOperand &Root)
const {
118 return selectSHXADD_UWOp(Root, ShAmt);
153#define GET_GLOBALISEL_PREDICATES_DECL
154#include "RISCVGenGlobalISel.inc"
155#undef GET_GLOBALISEL_PREDICATES_DECL
157#define GET_GLOBALISEL_TEMPORARIES_DECL
158#include "RISCVGenGlobalISel.inc"
159#undef GET_GLOBALISEL_TEMPORARIES_DECL
164#define GET_GLOBALISEL_IMPL
165#include "RISCVGenGlobalISel.inc"
166#undef GET_GLOBALISEL_IMPL
168RISCVInstructionSelector::RISCVInstructionSelector(
171 : STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()), RBI(RBI),
175#include
"RISCVGenGlobalISel.inc"
178#include
"RISCVGenGlobalISel.inc"
185 unsigned ShiftWidth)
const {
195 ShAmtReg = ZExtSrcReg;
215 if (ShMask.isSubsetOf(AndMask)) {
216 ShAmtReg = AndSrcReg;
220 KnownBits Known = KB->getKnownBits(AndSrcReg);
221 if (ShMask.isSubsetOf(AndMask | Known.
Zero))
222 ShAmtReg = AndSrcReg;
229 if (Imm != 0 &&
Imm.urem(ShiftWidth) == 0)
234 if (Imm != 0 &&
Imm.urem(ShiftWidth) == 0) {
237 ShAmtReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
238 unsigned NegOpc = Subtarget->is64Bit() ? RISCV::SUBW : RISCV::SUB;
245 if (
Imm.urem(ShiftWidth) == ShiftWidth - 1) {
248 ShAmtReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
263 unsigned Bits)
const {
269 if (RootDef->
getOpcode() == TargetOpcode::G_SEXT_INREG &&
275 unsigned Size =
MRI->getType(RootReg).getScalarSizeInBits();
276 if ((
Size - KB->computeNumSignBits(RootReg)) <
Bits)
284 unsigned Bits)
const {
296 MRI->getType(RegX).getScalarSizeInBits() ==
Bits)
299 unsigned Size =
MRI->getType(RootReg).getScalarSizeInBits();
308 unsigned ShAmt)
const {
315 const unsigned XLen = STI.getXLen();
334 if (
Mask.isShiftedMask()) {
335 unsigned Leading = XLen -
Mask.getActiveBits();
336 unsigned Trailing =
Mask.countr_zero();
339 if (*LeftShift && Leading == 0 && C2.
ult(Trailing) && Trailing == ShAmt) {
340 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
351 if (!*LeftShift && Leading == C2 && Trailing == ShAmt) {
352 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
356 .addImm(Leading + Trailing);
377 unsigned Leading = XLen -
Mask.getActiveBits();
378 unsigned Trailing =
Mask.countr_zero();
391 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
406 unsigned ShAmt)
const {
424 if (
Mask.isShiftedMask()) {
425 unsigned Leading =
Mask.countl_zero();
426 unsigned Trailing =
Mask.countr_zero();
427 if (Leading == 32 - ShAmt && C2 == Trailing && Trailing > ShAmt) {
428 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
444 assert(Root.
isReg() &&
"Expected operand to be a Register");
447 if (RootDef->
getOpcode() == TargetOpcode::G_CONSTANT) {
449 if (
C->getValue().isAllOnes())
457 if (isUInt<5>(
C->getZExtValue())) {
466RISCVInstructionSelector::selectAddrRegImm(
MachineOperand &Root)
const {
471 if (RootDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX) {
478 if (isBaseWithConstantOffset(Root, *
MRI)) {
485 if (isInt<12>(RHSC)) {
486 if (LHSDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX)
509 case CmpInst::Predicate::ICMP_EQ:
511 case CmpInst::Predicate::ICMP_NE:
513 case CmpInst::Predicate::ICMP_ULT:
515 case CmpInst::Predicate::ICMP_SLT:
517 case CmpInst::Predicate::ICMP_UGE:
519 case CmpInst::Predicate::ICMP_SGE:
541 case CmpInst::Predicate::ICMP_SGT:
549 case CmpInst::Predicate::ICMP_SLT:
566 case CmpInst::Predicate::ICMP_EQ:
567 case CmpInst::Predicate::ICMP_NE:
568 case CmpInst::Predicate::ICMP_ULT:
569 case CmpInst::Predicate::ICMP_SLT:
570 case CmpInst::Predicate::ICMP_UGE:
571 case CmpInst::Predicate::ICMP_SGE:
574 case CmpInst::Predicate::ICMP_SGT:
575 case CmpInst::Predicate::ICMP_SLE:
576 case CmpInst::Predicate::ICMP_UGT:
577 case CmpInst::Predicate::ICMP_ULE:
585 CC = getRISCVCCFromICmp(Pred);
591 preISelLower(
MI, MIB);
592 const unsigned Opc =
MI.getOpcode();
594 if (!
MI.isPreISelOpcode() || Opc == TargetOpcode::G_PHI) {
595 if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI) {
596 const Register DefReg =
MI.getOperand(0).getReg();
597 const LLT DefTy =
MRI->getType(DefReg);
600 MRI->getRegClassOrRegBank(DefReg);
603 dyn_cast<const TargetRegisterClass *>(RegClassOrBank);
610 const RegisterBank &RB = *cast<const RegisterBank *>(RegClassOrBank);
611 DefRC = getRegClassForTypeOnBank(DefTy, RB);
618 MI.setDesc(
TII.get(TargetOpcode::PHI));
619 return RBI.constrainGenericRegister(DefReg, *DefRC, *
MRI);
629 if (selectImpl(
MI, *CoverageInfo))
633 case TargetOpcode::G_ANYEXT:
634 case TargetOpcode::G_PTRTOINT:
635 case TargetOpcode::G_INTTOPTR:
636 case TargetOpcode::G_TRUNC:
637 case TargetOpcode::G_FREEZE:
639 case TargetOpcode::G_CONSTANT: {
641 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
643 if (!materializeImm(DstReg, Imm, MIB))
646 MI.eraseFromParent();
649 case TargetOpcode::G_FCONSTANT: {
653 const APFloat &FPimm =
MI.getOperand(1).getFPImm()->getValueAPF();
655 unsigned Size =
MRI->getType(DstReg).getSizeInBits();
656 if (
Size == 16 ||
Size == 32 || (
Size == 64 && Subtarget->is64Bit())) {
657 Register GPRReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
658 if (!materializeImm(GPRReg,
Imm.getSExtValue(), MIB))
661 unsigned Opcode =
Size == 64 ? RISCV::FMV_D_X
662 :
Size == 32 ? RISCV::FMV_W_X
664 auto FMV = MIB.buildInstr(Opcode, {DstReg}, {GPRReg});
665 if (!FMV.constrainAllUses(
TII,
TRI, RBI))
669 "Unexpected size or subtarget");
671 Register GPRRegHigh =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
672 Register GPRRegLow =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
673 if (!materializeImm(GPRRegHigh,
Imm.extractBits(32, 32).getSExtValue(),
676 if (!materializeImm(GPRRegLow,
Imm.trunc(32).getSExtValue(), MIB))
679 RISCV::BuildPairF64Pseudo, {DstReg}, {GPRRegLow, GPRRegHigh});
684 MI.eraseFromParent();
687 case TargetOpcode::G_GLOBAL_VALUE: {
688 auto *GV =
MI.getOperand(1).getGlobal();
689 if (GV->isThreadLocal()) {
694 return selectAddr(
MI, MIB, GV->isDSOLocal(), GV->hasExternalWeakLinkage());
696 case TargetOpcode::G_JUMP_TABLE:
697 case TargetOpcode::G_CONSTANT_POOL:
698 return selectAddr(
MI, MIB,
MRI);
699 case TargetOpcode::G_BRCOND: {
705 .addMBB(
MI.getOperand(1).getMBB());
706 MI.eraseFromParent();
709 case TargetOpcode::G_BRINDIRECT:
710 MI.setDesc(
TII.get(RISCV::PseudoBRIND));
713 case TargetOpcode::G_FRAME_INDEX: {
717 MI.setDesc(
TII.get(RISCV::ADDI));
721 case TargetOpcode::G_SELECT:
722 return selectSelect(
MI, MIB);
723 case TargetOpcode::G_FCMP:
724 return selectFPCompare(
MI, MIB);
725 case TargetOpcode::G_FENCE: {
730 emitFence(FenceOrdering, FenceSSID, MIB);
731 MI.eraseFromParent();
734 case TargetOpcode::G_IMPLICIT_DEF:
735 return selectImplicitDef(
MI, MIB);
736 case TargetOpcode::G_MERGE_VALUES:
738 case TargetOpcode::G_UNMERGE_VALUES:
747 assert(
MI.getOpcode() == TargetOpcode::G_MERGE_VALUES);
750 if (
MI.getNumOperands() != 3)
755 if (!isRegInFprb(Dst) || !isRegInGprb(
Lo) || !isRegInGprb(
Hi))
757 MI.setDesc(
TII.get(RISCV::BuildPairF64Pseudo));
761bool RISCVInstructionSelector::selectUnmergeValues(
763 assert(
MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
766 if (
MI.getNumOperands() != 3)
771 if (!isRegInFprb(Src) || !isRegInGprb(
Lo) || !isRegInGprb(
Hi))
773 MI.setDesc(
TII.get(RISCV::SplitF64Pseudo));
780 assert(
MRI->getType(PtrReg).isPointer() &&
"Operand is not a pointer!");
784 MRI->setRegBank(PtrToInt.getReg(0), RBI.getRegBank(RISCV::GPRBRegBankID));
785 Op.setReg(PtrToInt.getReg(0));
786 return select(*PtrToInt);
791 switch (
MI.getOpcode()) {
792 case TargetOpcode::G_PTR_ADD: {
796 replacePtrWithInt(
MI.getOperand(1), MIB);
797 MI.setDesc(
TII.get(TargetOpcode::G_ADD));
798 MRI->setType(DstReg, sXLen);
801 case TargetOpcode::G_PTRMASK: {
804 replacePtrWithInt(
MI.getOperand(1), MIB);
805 MI.setDesc(
TII.get(TargetOpcode::G_AND));
806 MRI->setType(DstReg, sXLen);
815 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
816 "Expected G_CONSTANT");
817 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
824 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
825 "Expected G_CONSTANT");
826 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
827 MIB.
addImm(STI.getXLen() - CstVal);
833 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
834 "Expected G_CONSTANT");
835 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
842 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
843 "Expected G_CONSTANT");
844 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
851 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
852 "Expected G_CONSTANT");
853 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
860 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
861 "Expected G_CONSTANT");
862 uint64_t C =
MI.getOperand(1).getCImm()->getZExtValue();
866void RISCVInstructionSelector::renderXLenSubTrailingOnes(
868 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
869 "Expected G_CONSTANT");
870 uint64_t C =
MI.getOperand(1).getCImm()->getZExtValue();
876 if (RB.
getID() == RISCV::GPRBRegBankID) {
878 return &RISCV::GPRRegClass;
881 if (RB.
getID() == RISCV::FPRBRegBankID) {
883 return &RISCV::FPR16RegClass;
885 return &RISCV::FPR32RegClass;
887 return &RISCV::FPR64RegClass;
890 if (RB.
getID() == RISCV::VRBRegBankID) {
892 return &RISCV::VRRegClass;
895 return &RISCV::VRM2RegClass;
898 return &RISCV::VRM4RegClass;
901 return &RISCV::VRM8RegClass;
907bool RISCVInstructionSelector::isRegInGprb(
Register Reg)
const {
908 return RBI.getRegBank(Reg, *
MRI,
TRI)->
getID() == RISCV::GPRBRegBankID;
911bool RISCVInstructionSelector::isRegInFprb(
Register Reg)
const {
912 return RBI.getRegBank(Reg, *
MRI,
TRI)->getID() == RISCV::FPRBRegBankID;
915bool RISCVInstructionSelector::selectCopy(
MachineInstr &
MI)
const {
922 MRI->getType(DstReg), *RBI.getRegBank(DstReg, *
MRI,
TRI));
924 "Register class not available for LLT, register bank combination");
929 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *
MRI)) {
935 MI.setDesc(
TII.get(RISCV::COPY));
941 assert(
MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
943 const Register DstReg =
MI.getOperand(0).getReg();
945 MRI->getType(DstReg), *RBI.getRegBank(DstReg, *
MRI,
TRI));
948 "Register class not available for LLT, register bank combination");
950 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *
MRI)) {
954 MI.setDesc(
TII.get(TargetOpcode::IMPLICIT_DEF));
958bool RISCVInstructionSelector::materializeImm(
Register DstReg, int64_t Imm,
962 RBI.constrainGenericRegister(DstReg, RISCV::GPRRegClass, *
MRI);
967 unsigned NumInsts = Seq.
size();
970 for (
unsigned i = 0; i < NumInsts; i++) {
972 ?
MRI->createVirtualRegister(&RISCV::GPRRegClass)
977 switch (
I.getOpndKind()) {
986 {SrcReg, Register(RISCV::X0)});
1008 bool IsExternWeak)
const {
1009 assert((
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
1010 MI.getOpcode() == TargetOpcode::G_JUMP_TABLE ||
1011 MI.getOpcode() == TargetOpcode::G_CONSTANT_POOL) &&
1012 "Unexpected opcode");
1017 const LLT DefTy =
MRI->getType(DefReg);
1023 if (
TM.isPositionIndependent() || Subtarget->allowTaggedGlobals()) {
1024 if (IsLocal && !Subtarget->allowTaggedGlobals()) {
1028 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1050 MI.eraseFromParent();
1054 switch (
TM.getCodeModel()) {
1057 getName(),
"Unsupported code model for lowering",
MI);
1064 Register AddrHiDest =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1077 MI.eraseFromParent();
1104 MI.eraseFromParent();
1111 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1120 auto &SelectMI = cast<GSelect>(
MI);
1126 Register DstReg = SelectMI.getReg(0);
1128 unsigned Opc = RISCV::Select_GPR_Using_CC_GPR;
1129 if (RBI.getRegBank(DstReg, *
MRI,
TRI)->getID() == RISCV::FPRBRegBankID) {
1130 unsigned Size =
MRI->getType(DstReg).getSizeInBits();
1131 Opc =
Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR
1132 : RISCV::Select_FPR64_Using_CC_GPR;
1140 .
addReg(SelectMI.getTrueReg())
1141 .
addReg(SelectMI.getFalseReg());
1142 MI.eraseFromParent();
1153 return Size == 16 ? RISCV::FLT_H :
Size == 32 ? RISCV::FLT_S : RISCV::FLT_D;
1155 return Size == 16 ? RISCV::FLE_H :
Size == 32 ? RISCV::FLE_S : RISCV::FLE_D;
1157 return Size == 16 ? RISCV::FEQ_H :
Size == 32 ? RISCV::FEQ_S : RISCV::FEQ_D;
1170 assert(!isLegalFCmpPredicate(Pred) &&
"Predicate already legal?");
1173 if (isLegalFCmpPredicate(InvPred)) {
1181 if (isLegalFCmpPredicate(InvPred)) {
1186 if (isLegalFCmpPredicate(InvPred)) {
1200 auto &CmpMI = cast<GFCmp>(
MI);
1207 unsigned Size =
MRI->getType(LHS).getSizeInBits();
1212 bool NeedInvert =
false;
1216 TmpReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1218 if (!
Cmp.constrainAllUses(
TII,
TRI, RBI))
1224 {&RISCV::GPRRegClass}, {
LHS,
RHS});
1225 if (!Cmp1.constrainAllUses(
TII,
TRI, RBI))
1228 {&RISCV::GPRRegClass}, {
RHS,
LHS});
1229 if (!Cmp2.constrainAllUses(
TII,
TRI, RBI))
1232 TmpReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1234 MIB.
buildInstr(RISCV::OR, {TmpReg}, {Cmp1.getReg(0), Cmp2.getReg(0)});
1235 if (!
Or.constrainAllUses(
TII,
TRI, RBI))
1242 {&RISCV::GPRRegClass}, {
LHS,
LHS});
1243 if (!Cmp1.constrainAllUses(
TII,
TRI, RBI))
1246 {&RISCV::GPRRegClass}, {
RHS,
RHS});
1247 if (!Cmp2.constrainAllUses(
TII,
TRI, RBI))
1250 TmpReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1252 MIB.
buildInstr(RISCV::AND, {TmpReg}, {Cmp1.getReg(0), Cmp2.getReg(0)});
1253 if (!
And.constrainAllUses(
TII,
TRI, RBI))
1260 auto Xor = MIB.
buildInstr(RISCV::XORI, {DstReg}, {TmpReg}).addImm(1);
1261 if (!
Xor.constrainAllUses(
TII,
TRI, RBI))
1265 MI.eraseFromParent();
1269void RISCVInstructionSelector::emitFence(
AtomicOrdering FenceOrdering,
1272 if (STI.hasStdExtZtso()) {
1275 if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
1285 MIB.
buildInstr(TargetOpcode::MEMBARRIER, {}, {});
1293 MIB.
buildInstr(TargetOpcode::MEMBARRIER, {}, {});
1299 unsigned Pred, Succ;
1300 switch (FenceOrdering) {
1303 case AtomicOrdering::AcquireRelease:
1307 case AtomicOrdering::Acquire:
1312 case AtomicOrdering::Release:
1317 case AtomicOrdering::SequentiallyConsistent:
1331 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)
static bool selectMergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
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
Contains matchers for matching SSA Machine Instructions.
This file declares the MachineIRBuilder class.
unsigned const TargetRegisterInfo * TRI
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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, GISelKnownBits *kb, 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 & 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 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()
SpecificConstantMatch m_SpecificICst(int64_t RequestedValue)
Matches a constant equal to RequestedValue.
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)
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, bool Imm=false)
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.
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)
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.
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.
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 MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.