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;
86 unsigned ShiftWidth)
const;
87 ComplexRendererFns selectShiftMaskXLen(
MachineOperand &Root)
const {
88 return selectShiftMask(Root, STI.
getXLen());
91 return selectShiftMask(Root, 32);
95 ComplexRendererFns selectSExtBits(
MachineOperand &Root,
unsigned Bits)
const;
96 template <
unsigned Bits>
98 return selectSExtBits(Root, Bits);
101 ComplexRendererFns selectZExtBits(
MachineOperand &Root,
unsigned Bits)
const;
102 template <
unsigned Bits>
104 return selectZExtBits(Root, Bits);
107 ComplexRendererFns selectSHXADDOp(
MachineOperand &Root,
unsigned ShAmt)
const;
108 template <
unsigned ShAmt>
110 return selectSHXADDOp(Root, ShAmt);
114 unsigned ShAmt)
const;
115 template <
unsigned ShAmt>
116 ComplexRendererFns selectSHXADD_UWOp(
MachineOperand &Root)
const {
117 return selectSHXADD_UWOp(Root, ShAmt);
159#define GET_GLOBALISEL_PREDICATES_DECL
160#include "RISCVGenGlobalISel.inc"
161#undef GET_GLOBALISEL_PREDICATES_DECL
163#define GET_GLOBALISEL_TEMPORARIES_DECL
164#include "RISCVGenGlobalISel.inc"
165#undef GET_GLOBALISEL_TEMPORARIES_DECL
170#define GET_GLOBALISEL_IMPL
171#include "RISCVGenGlobalISel.inc"
172#undef GET_GLOBALISEL_IMPL
174RISCVInstructionSelector::RISCVInstructionSelector(
177 : STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()), RBI(RBI),
181#include
"RISCVGenGlobalISel.inc"
184#include
"RISCVGenGlobalISel.inc"
191 unsigned ShiftWidth)
const {
201 ShAmtReg = ZExtSrcReg;
221 if (ShMask.isSubsetOf(AndMask)) {
222 ShAmtReg = AndSrcReg;
226 KnownBits Known = KB->getKnownBits(AndSrcReg);
227 if (ShMask.isSubsetOf(AndMask | Known.
Zero))
228 ShAmtReg = AndSrcReg;
235 if (Imm != 0 &&
Imm.urem(ShiftWidth) == 0)
240 if (Imm != 0 &&
Imm.urem(ShiftWidth) == 0) {
243 ShAmtReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
244 unsigned NegOpc = Subtarget->is64Bit() ? RISCV::SUBW : RISCV::SUB;
251 if (
Imm.urem(ShiftWidth) == ShiftWidth - 1) {
254 ShAmtReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
269 unsigned Bits)
const {
275 if (RootDef->
getOpcode() == TargetOpcode::G_SEXT_INREG &&
281 unsigned Size =
MRI->getType(RootReg).getScalarSizeInBits();
282 if ((
Size - KB->computeNumSignBits(RootReg)) <
Bits)
290 unsigned Bits)
const {
302 MRI->getType(RegX).getScalarSizeInBits() ==
Bits)
305 unsigned Size =
MRI->getType(RootReg).getScalarSizeInBits();
314 unsigned ShAmt)
const {
321 const unsigned XLen = STI.getXLen();
340 if (
Mask.isShiftedMask()) {
341 unsigned Leading = XLen -
Mask.getActiveBits();
342 unsigned Trailing =
Mask.countr_zero();
345 if (*LeftShift && Leading == 0 && C2.
ult(Trailing) && Trailing == ShAmt) {
346 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
357 if (!*LeftShift && Leading == C2 && Trailing == ShAmt) {
358 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
362 .addImm(Leading + Trailing);
383 unsigned Leading = XLen -
Mask.getActiveBits();
384 unsigned Trailing =
Mask.countr_zero();
397 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
412 unsigned ShAmt)
const {
430 if (
Mask.isShiftedMask()) {
431 unsigned Leading =
Mask.countl_zero();
432 unsigned Trailing =
Mask.countr_zero();
433 if (Leading == 32 - ShAmt && C2 == Trailing && Trailing > ShAmt) {
434 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
450 assert(Root.
isReg() &&
"Expected operand to be a Register");
453 if (RootDef->
getOpcode() == TargetOpcode::G_CONSTANT) {
455 if (
C->getValue().isAllOnes())
463 if (isUInt<5>(
C->getZExtValue())) {
472RISCVInstructionSelector::selectAddrRegImm(
MachineOperand &Root)
const {
477 if (RootDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX) {
484 if (isBaseWithConstantOffset(Root, *
MRI)) {
491 if (isInt<12>(RHSC)) {
492 if (LHSDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX)
515 case CmpInst::Predicate::ICMP_EQ:
517 case CmpInst::Predicate::ICMP_NE:
519 case CmpInst::Predicate::ICMP_ULT:
521 case CmpInst::Predicate::ICMP_SLT:
523 case CmpInst::Predicate::ICMP_UGE:
525 case CmpInst::Predicate::ICMP_SGE:
547 case CmpInst::Predicate::ICMP_SGT:
555 case CmpInst::Predicate::ICMP_SLT:
572 case CmpInst::Predicate::ICMP_EQ:
573 case CmpInst::Predicate::ICMP_NE:
574 case CmpInst::Predicate::ICMP_ULT:
575 case CmpInst::Predicate::ICMP_SLT:
576 case CmpInst::Predicate::ICMP_UGE:
577 case CmpInst::Predicate::ICMP_SGE:
580 case CmpInst::Predicate::ICMP_SGT:
581 case CmpInst::Predicate::ICMP_SLE:
582 case CmpInst::Predicate::ICMP_UGT:
583 case CmpInst::Predicate::ICMP_ULE:
591 CC = getRISCVCCFromICmp(Pred);
597 preISelLower(
MI, MIB);
598 const unsigned Opc =
MI.getOpcode();
600 if (!
MI.isPreISelOpcode() || Opc == TargetOpcode::G_PHI) {
601 if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI) {
602 const Register DefReg =
MI.getOperand(0).getReg();
603 const LLT DefTy =
MRI->getType(DefReg);
606 MRI->getRegClassOrRegBank(DefReg);
609 dyn_cast<const TargetRegisterClass *>(RegClassOrBank);
616 const RegisterBank &RB = *cast<const RegisterBank *>(RegClassOrBank);
617 DefRC = getRegClassForTypeOnBank(DefTy, RB);
624 MI.setDesc(
TII.get(TargetOpcode::PHI));
625 return RBI.constrainGenericRegister(DefReg, *DefRC, *
MRI);
635 if (selectImpl(
MI, *CoverageInfo))
639 case TargetOpcode::G_ANYEXT:
640 case TargetOpcode::G_PTRTOINT:
641 case TargetOpcode::G_INTTOPTR:
642 case TargetOpcode::G_TRUNC:
643 case TargetOpcode::G_FREEZE:
645 case TargetOpcode::G_CONSTANT: {
647 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
649 if (!materializeImm(DstReg, Imm, MIB))
652 MI.eraseFromParent();
655 case TargetOpcode::G_FCONSTANT: {
659 const APFloat &FPimm =
MI.getOperand(1).getFPImm()->getValueAPF();
661 unsigned Size =
MRI->getType(DstReg).getSizeInBits();
662 if (
Size == 16 ||
Size == 32 || (
Size == 64 && Subtarget->is64Bit())) {
663 Register GPRReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
664 if (!materializeImm(GPRReg,
Imm.getSExtValue(), MIB))
667 unsigned Opcode =
Size == 64 ? RISCV::FMV_D_X
668 :
Size == 32 ? RISCV::FMV_W_X
670 auto FMV = MIB.buildInstr(Opcode, {DstReg}, {GPRReg});
671 if (!FMV.constrainAllUses(
TII,
TRI, RBI))
675 "Unexpected size or subtarget");
677 Register GPRRegHigh =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
678 Register GPRRegLow =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
679 if (!materializeImm(GPRRegHigh,
Imm.extractBits(32, 32).getSExtValue(),
682 if (!materializeImm(GPRRegLow,
Imm.trunc(32).getSExtValue(), MIB))
685 RISCV::BuildPairF64Pseudo, {DstReg}, {GPRRegLow, GPRRegHigh});
690 MI.eraseFromParent();
693 case TargetOpcode::G_GLOBAL_VALUE: {
694 auto *GV =
MI.getOperand(1).getGlobal();
695 if (GV->isThreadLocal()) {
700 return selectAddr(
MI, MIB, GV->isDSOLocal(), GV->hasExternalWeakLinkage());
702 case TargetOpcode::G_JUMP_TABLE:
703 case TargetOpcode::G_CONSTANT_POOL:
704 return selectAddr(
MI, MIB,
MRI);
705 case TargetOpcode::G_BRCOND: {
711 .addMBB(
MI.getOperand(1).getMBB());
712 MI.eraseFromParent();
715 case TargetOpcode::G_BRINDIRECT:
716 MI.setDesc(
TII.get(RISCV::PseudoBRIND));
719 case TargetOpcode::G_SELECT:
720 return selectSelect(
MI, MIB);
721 case TargetOpcode::G_FCMP:
722 return selectFPCompare(
MI, MIB);
723 case TargetOpcode::G_FENCE: {
728 emitFence(FenceOrdering, FenceSSID, MIB);
729 MI.eraseFromParent();
732 case TargetOpcode::G_IMPLICIT_DEF:
733 return selectImplicitDef(
MI, MIB);
734 case TargetOpcode::G_UNMERGE_VALUES:
741bool RISCVInstructionSelector::selectUnmergeValues(
743 assert(
MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
745 if (!Subtarget->hasStdExtZfa())
749 if (
MI.getNumOperands() != 3)
754 if (!isRegInFprb(Src) || !isRegInGprb(
Lo) || !isRegInGprb(
Hi))
765 MI.eraseFromParent();
772 assert(
MRI->getType(PtrReg).isPointer() &&
"Operand is not a pointer!");
776 MRI->setRegBank(PtrToInt.getReg(0), RBI.getRegBank(RISCV::GPRBRegBankID));
777 Op.setReg(PtrToInt.getReg(0));
778 return select(*PtrToInt);
783 switch (
MI.getOpcode()) {
784 case TargetOpcode::G_PTR_ADD: {
788 replacePtrWithInt(
MI.getOperand(1), MIB);
789 MI.setDesc(
TII.get(TargetOpcode::G_ADD));
790 MRI->setType(DstReg, sXLen);
793 case TargetOpcode::G_PTRMASK: {
796 replacePtrWithInt(
MI.getOperand(1), MIB);
797 MI.setDesc(
TII.get(TargetOpcode::G_AND));
798 MRI->setType(DstReg, sXLen);
807 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
808 "Expected G_CONSTANT");
809 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
816 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
817 "Expected G_CONSTANT");
818 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
819 MIB.
addImm(STI.getXLen() - CstVal);
825 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
826 "Expected G_CONSTANT");
827 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
834 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
835 "Expected G_CONSTANT");
836 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
843 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
844 "Expected G_CONSTANT");
845 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
852 assert(
MI.getOpcode() == TargetOpcode::G_FRAME_INDEX && OpIdx == -1 &&
853 "Expected G_FRAME_INDEX");
854 MIB.
add(
MI.getOperand(1));
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();
877 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
878 "Expected G_CONSTANT");
879 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
880 int64_t Adj =
Imm < 0 ? -2048 : 2047;
887 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
888 "Expected G_CONSTANT");
889 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue() < 0 ? -2048 : 2047;
895 if (RB.
getID() == RISCV::GPRBRegBankID) {
897 return &RISCV::GPRRegClass;
900 if (RB.
getID() == RISCV::FPRBRegBankID) {
902 return &RISCV::FPR16RegClass;
904 return &RISCV::FPR32RegClass;
906 return &RISCV::FPR64RegClass;
909 if (RB.
getID() == RISCV::VRBRegBankID) {
911 return &RISCV::VRRegClass;
914 return &RISCV::VRM2RegClass;
917 return &RISCV::VRM4RegClass;
920 return &RISCV::VRM8RegClass;
926bool RISCVInstructionSelector::isRegInGprb(
Register Reg)
const {
927 return RBI.getRegBank(Reg, *
MRI,
TRI)->
getID() == RISCV::GPRBRegBankID;
930bool RISCVInstructionSelector::isRegInFprb(
Register Reg)
const {
931 return RBI.getRegBank(Reg, *
MRI,
TRI)->getID() == RISCV::FPRBRegBankID;
934bool RISCVInstructionSelector::selectCopy(
MachineInstr &
MI)
const {
941 MRI->getType(DstReg), *RBI.getRegBank(DstReg, *
MRI,
TRI));
943 "Register class not available for LLT, register bank combination");
948 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *
MRI)) {
954 MI.setDesc(
TII.get(RISCV::COPY));
960 assert(
MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
962 const Register DstReg =
MI.getOperand(0).getReg();
964 MRI->getType(DstReg), *RBI.getRegBank(DstReg, *
MRI,
TRI));
967 "Register class not available for LLT, register bank combination");
969 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *
MRI)) {
973 MI.setDesc(
TII.get(TargetOpcode::IMPLICIT_DEF));
977bool RISCVInstructionSelector::materializeImm(
Register DstReg, int64_t Imm,
981 RBI.constrainGenericRegister(DstReg, RISCV::GPRRegClass, *
MRI);
986 unsigned NumInsts = Seq.
size();
989 for (
unsigned i = 0; i < NumInsts; i++) {
991 ?
MRI->createVirtualRegister(&RISCV::GPRRegClass)
996 switch (
I.getOpndKind()) {
1005 {SrcReg, Register(RISCV::X0)});
1027 bool IsExternWeak)
const {
1028 assert((
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
1029 MI.getOpcode() == TargetOpcode::G_JUMP_TABLE ||
1030 MI.getOpcode() == TargetOpcode::G_CONSTANT_POOL) &&
1031 "Unexpected opcode");
1036 const LLT DefTy =
MRI->getType(DefReg);
1042 if (
TM.isPositionIndependent() || Subtarget->allowTaggedGlobals()) {
1043 if (IsLocal && !Subtarget->allowTaggedGlobals()) {
1047 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1069 MI.eraseFromParent();
1073 switch (
TM.getCodeModel()) {
1076 getName(),
"Unsupported code model for lowering",
MI);
1083 Register AddrHiDest =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1096 MI.eraseFromParent();
1123 MI.eraseFromParent();
1130 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1139 auto &SelectMI = cast<GSelect>(
MI);
1145 Register DstReg = SelectMI.getReg(0);
1147 unsigned Opc = RISCV::Select_GPR_Using_CC_GPR;
1148 if (RBI.getRegBank(DstReg, *
MRI,
TRI)->getID() == RISCV::FPRBRegBankID) {
1149 unsigned Size =
MRI->getType(DstReg).getSizeInBits();
1150 Opc =
Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR
1151 : RISCV::Select_FPR64_Using_CC_GPR;
1159 .
addReg(SelectMI.getTrueReg())
1160 .
addReg(SelectMI.getFalseReg());
1161 MI.eraseFromParent();
1172 return Size == 16 ? RISCV::FLT_H :
Size == 32 ? RISCV::FLT_S : RISCV::FLT_D;
1174 return Size == 16 ? RISCV::FLE_H :
Size == 32 ? RISCV::FLE_S : RISCV::FLE_D;
1176 return Size == 16 ? RISCV::FEQ_H :
Size == 32 ? RISCV::FEQ_S : RISCV::FEQ_D;
1189 assert(!isLegalFCmpPredicate(Pred) &&
"Predicate already legal?");
1192 if (isLegalFCmpPredicate(InvPred)) {
1200 if (isLegalFCmpPredicate(InvPred)) {
1205 if (isLegalFCmpPredicate(InvPred)) {
1219 auto &CmpMI = cast<GFCmp>(
MI);
1226 unsigned Size =
MRI->getType(LHS).getSizeInBits();
1231 bool NeedInvert =
false;
1235 TmpReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1237 if (!
Cmp.constrainAllUses(
TII,
TRI, RBI))
1243 {&RISCV::GPRRegClass}, {
LHS,
RHS});
1244 if (!Cmp1.constrainAllUses(
TII,
TRI, RBI))
1247 {&RISCV::GPRRegClass}, {
RHS,
LHS});
1248 if (!Cmp2.constrainAllUses(
TII,
TRI, RBI))
1251 TmpReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1253 MIB.
buildInstr(RISCV::OR, {TmpReg}, {Cmp1.getReg(0), Cmp2.getReg(0)});
1254 if (!
Or.constrainAllUses(
TII,
TRI, RBI))
1261 {&RISCV::GPRRegClass}, {
LHS,
LHS});
1262 if (!Cmp1.constrainAllUses(
TII,
TRI, RBI))
1265 {&RISCV::GPRRegClass}, {
RHS,
RHS});
1266 if (!Cmp2.constrainAllUses(
TII,
TRI, RBI))
1269 TmpReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1271 MIB.
buildInstr(RISCV::AND, {TmpReg}, {Cmp1.getReg(0), Cmp2.getReg(0)});
1272 if (!
And.constrainAllUses(
TII,
TRI, RBI))
1279 auto Xor = MIB.
buildInstr(RISCV::XORI, {DstReg}, {TmpReg}).addImm(1);
1280 if (!
Xor.constrainAllUses(
TII,
TRI, RBI))
1284 MI.eraseFromParent();
1288void RISCVInstructionSelector::emitFence(
AtomicOrdering FenceOrdering,
1291 if (STI.hasStdExtZtso()) {
1294 if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
1304 MIB.
buildInstr(TargetOpcode::MEMBARRIER, {}, {});
1312 MIB.
buildInstr(TargetOpcode::MEMBARRIER, {}, {});
1318 unsigned Pred, Succ;
1319 switch (FenceOrdering) {
1322 case AtomicOrdering::AcquireRelease:
1326 case AtomicOrdering::Acquire:
1331 case AtomicOrdering::Release:
1336 case AtomicOrdering::SequentiallyConsistent:
1350 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 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 & 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 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.