29using namespace LegalityPredicates;
30using namespace LegalizeMutations;
37 return Query.Types[TypeIdx].isScalar() &&
38 ((ST.hasStdExtF() && Query.Types[TypeIdx].getSizeInBits() == 32) ||
39 (ST.hasStdExtD() && Query.Types[TypeIdx].getSizeInBits() == 64));
45 std::initializer_list<LLT> IntOrFPVecTys,
48 return ST.hasVInstructions() &&
49 (Query.Types[TypeIdx].getScalarSizeInBits() != 64 ||
50 ST.hasVInstructionsI64()) &&
51 (Query.Types[TypeIdx].getElementCount().getKnownMinValue() != 1 ||
62 return ST.hasVInstructions() &&
63 (Query.Types[TypeIdx].getElementCount().getKnownMinValue() != 1 ||
70 : STI(ST), XLen(STI.getXLen()), sXLen(
LLT::scalar(XLen)) {
113 using namespace TargetOpcode;
115 auto BoolVecTys = {nxv1s1, nxv2s1, nxv4s1, nxv8s1, nxv16s1, nxv32s1, nxv64s1};
117 auto IntOrFPVecTys = {nxv1s8, nxv2s8, nxv4s8, nxv8s8, nxv16s8, nxv32s8,
118 nxv64s8, nxv1s16, nxv2s16, nxv4s16, nxv8s16, nxv16s16,
119 nxv32s16, nxv1s32, nxv2s32, nxv4s32, nxv8s32, nxv16s32,
120 nxv1s64, nxv2s64, nxv4s64, nxv8s64};
123 .legalFor({s32, sXLen})
129 {G_UADDE, G_UADDO, G_USUBE, G_USUBO}).lower();
136 ShiftActions.
legalFor({{s32, s32}, {s32, sXLen}, {sXLen, sXLen}})
137 .widenScalarToNextPow2(0)
147 ExtActions.legalFor({{sXLen, s32}});
159 for (
unsigned Op : {G_MERGE_VALUES, G_UNMERGE_VALUES}) {
161 unsigned BigTyIdx =
Op == G_MERGE_VALUES ? 0 : 1;
162 unsigned LitTyIdx =
Op == G_MERGE_VALUES ? 1 : 0;
163 if (XLen == 32 && ST.hasStdExtD()) {
164 MergeUnmergeActions.legalIf(
167 MergeUnmergeActions.widenScalarToNextPow2(LitTyIdx, XLen)
168 .widenScalarToNextPow2(BigTyIdx, XLen)
169 .clampScalar(LitTyIdx, sXLen, sXLen)
170 .clampScalar(BigTyIdx, sXLen, sXLen);
176 if (ST.hasStdExtZbb() || ST.hasStdExtZbkb()) {
177 RotateActions.
legalFor({{s32, sXLen}, {sXLen, sXLen}});
183 RotateActions.
lower();
194 if (ST.hasStdExtZbb() || ST.hasStdExtZbkb())
195 BSWAPActions.legalFor({sXLen}).clampScalar(0, sXLen, sXLen);
197 BSWAPActions.maxScalar(0, sXLen).lower();
200 auto &CountZerosUndefActions =
202 if (ST.hasStdExtZbb()) {
203 CountZerosActions.
legalFor({{s32, s32}, {sXLen, sXLen}})
204 .clampScalar(0, s32, sXLen)
211 CountZerosUndefActions.
lower();
214 if (ST.hasStdExtZbb()) {
215 CTPOPActions.legalFor({{s32, s32}, {sXLen, sXLen}})
216 .clampScalar(0, s32, sXLen)
217 .widenScalarToNextPow2(0)
218 .scalarSameSizeAs(1, 0);
220 CTPOPActions.maxScalar(0, sXLen).scalarSameSizeAs(1, 0).lower();
224 ConstantActions.legalFor({s32, p0});
226 ConstantActions.customFor({s64});
227 ConstantActions.widenScalarToNextPow2(0).clampScalar(0, s32, sXLen);
238 .
legalFor({{sXLen, sXLen}, {sXLen, p0}})
245 auto &SelectActions =
247 .
legalFor({{s32, sXLen}, {p0, sXLen}})
250 if (XLen == 64 || ST.hasStdExtD())
251 SelectActions.
legalFor({{s64, sXLen}});
253 .
clampScalar(0, s32, (XLen == 64 || ST.hasStdExtD()) ? s64 : s32)
256 auto &LoadStoreActions =
258 .legalForTypesWithMemDesc({{s32, p0, s8, 8},
261 {p0, p0, sXLen, XLen}});
262 auto &ExtLoadActions =
264 .legalForTypesWithMemDesc({{s32, p0, s8, 8}, {s32, p0, s16, 16}});
269 {s64, p0, s64, 64}});
271 {{s64, p0, s8, 8}, {s64, p0, s16, 16}, {s64, p0, s32, 32}});
272 }
else if (ST.hasStdExtD()) {
282 .clampScalar(0, sXLen, sXLen);
286 .clampScalar(1, sXLen, sXLen);
296 .widenScalarToNextPow2(0)
302 if (ST.hasStdExtM() || ST.hasStdExtZmmul()) {
305 .widenScalarToNextPow2(0)
318 .widenScalarToNextPow2(0)
333 if (ST.hasStdExtM()) {
335 .legalFor({s32, sXLen})
336 .libcallFor({sDoubleXLen})
337 .clampScalar(0, s32, sDoubleXLen)
341 .libcallFor({sXLen, sDoubleXLen})
342 .clampScalar(0, sXLen, sDoubleXLen)
347 if (ST.hasStdExtZbb())
348 AbsActions.customFor({s32, sXLen}).minScalar(0, sXLen);
351 auto &MinMaxActions =
353 if (ST.hasStdExtZbb())
354 MinMaxActions.
legalFor({sXLen}).minScalar(0, sXLen);
355 MinMaxActions.
lower();
366 G_FABS, G_FSQRT, G_FMAXNUM, G_FMINNUM})
374 return (ST.hasStdExtD() &&
typeIs(0, s32)(Query) &&
379 return (ST.hasStdExtD() &&
typeIs(0, s64)(Query) &&
408 .libcallFor({s32, s64});
437 if (ST.hasVInstructionsF64() && ST.hasStdExtD())
440 else if (ST.hasVInstructionsI64())
460 switch (IntrinsicID) {
463 case Intrinsic::vacopy: {
474 LLT PtrTy =
MRI.getType(DstLst);
480 auto Tmp = MIRBuilder.
buildLoad(PtrTy,
MI.getOperand(2), *LoadMMO);
485 MIRBuilder.
buildStore(Tmp, DstLst, *StoreMMO);
487 MI.eraseFromParent();
493bool RISCVLegalizerInfo::legalizeShlAshrLshr(
496 assert(
MI.getOpcode() == TargetOpcode::G_ASHR ||
497 MI.getOpcode() == TargetOpcode::G_LSHR ||
498 MI.getOpcode() == TargetOpcode::G_SHL);
507 uint64_t Amount = VRegAndVal->Value.getZExtValue();
512 MI.getOperand(2).setReg(ExtCst.getReg(0));
520 assert(
MI.getOpcode() == TargetOpcode::G_VASTART);
527 MIRBuilder.
buildStore(FINAddr,
MI.getOperand(0).getReg(),
528 *
MI.memoperands()[0]);
529 MI.eraseFromParent();
533bool RISCVLegalizerInfo::shouldBeInConstantPool(
APInt APImm,
534 bool ShouldOptForSize)
const {
554 if (ShouldOptForSize)
562 unsigned ShiftAmt, AddOpc;
583 uint64_t Val =
MI.getOperand(1).getCImm()->getZExtValue();
587 auto VLENB = MIB.
buildInstr(RISCV::G_READ_VLENB, {XLenTy}, {});
589 }
else if (
Log2 > 3) {
590 auto VLENB = MIB.
buildInstr(RISCV::G_READ_VLENB, {XLenTy}, {});
593 MIB.
buildInstr(RISCV::G_READ_VLENB, {Dst}, {});
595 }
else if ((Val % 8) == 0) {
598 auto VLENB = MIB.
buildInstr(RISCV::G_READ_VLENB, {XLenTy}, {});
601 auto VLENB = MIB.
buildInstr(RISCV::G_READ_VLENB, {XLenTy}, {});
605 MI.eraseFromParent();
616 unsigned Opc =
MI.getOpcode();
617 assert(Opc == TargetOpcode::G_ZEXT || Opc == TargetOpcode::G_SEXT ||
618 Opc == TargetOpcode::G_ANYEXT);
624 LLT DstTy =
MRI.getType(Dst);
625 int64_t ExtTrueVal = Opc == TargetOpcode::G_SEXT ? -1 : 1;
632 MI.eraseFromParent();
651 return MIB.
buildInstr(RISCV::G_VMSET_VL, {MaskTy}, {VL});
656static std::pair<MachineInstrBuilder, Register>
659 LLT VecTy = Dst.getLLTTy(
MRI);
678 return MIB.
buildInstr(RISCV::G_SPLAT_VECTOR_SPLIT_I64_VL, {Dst},
679 {Passthru,
Lo,
Hi, VL});
689 Unmerge.getReg(1), VL, MIB,
MRI);
698 assert(
MI.getOpcode() == TargetOpcode::G_SPLAT_VECTOR);
703 Register SplatVal =
MI.getOperand(1).getReg();
705 LLT VecTy =
MRI.getType(Dst);
709 if (XLenTy.getSizeInBits() == 32 &&
714 MI.eraseFromParent();
722 MIB.
buildInstr(RISCV::G_VMSET_VL, {Dst}, {VL});
723 MI.eraseFromParent();
728 MIB.
buildInstr(RISCV::G_VMCLR_VL, {Dst}, {VL});
729 MI.eraseFromParent();
737 auto ZExtSplatVal = MIB.
buildZExt(InterEltTy, SplatVal);
744 MI.eraseFromParent();
754 switch (
MI.getOpcode()) {
758 case TargetOpcode::G_ABS:
761 case TargetOpcode::G_CONSTANT: {
765 bool ShouldOptForSize =
F.hasOptSize() ||
F.hasMinSize();
767 if (!shouldBeInConstantPool(ConstVal->
getValue(), ShouldOptForSize))
771 case TargetOpcode::G_SHL:
772 case TargetOpcode::G_ASHR:
773 case TargetOpcode::G_LSHR:
774 return legalizeShlAshrLshr(
MI, MIRBuilder, Observer);
775 case TargetOpcode::G_SEXT_INREG: {
777 int64_t SizeInBits =
MI.getOperand(2).getImm();
778 if (SizeInBits == 32)
784 case TargetOpcode::G_IS_FPCLASS: {
785 Register GISFPCLASS =
MI.getOperand(0).getReg();
796 auto GFClass = MIB.
buildInstr(RISCV::G_FCLASS, {sXLen}, {Src});
797 auto And = MIB.
buildAnd(sXLen, GFClass, FClassMask);
800 MI.eraseFromParent();
803 case TargetOpcode::G_VASTART:
804 return legalizeVAStart(
MI, MIRBuilder);
805 case TargetOpcode::G_VSCALE:
806 return legalizeVScale(
MI, MIRBuilder);
807 case TargetOpcode::G_ZEXT:
808 case TargetOpcode::G_SEXT:
809 case TargetOpcode::G_ANYEXT:
810 return legalizeExt(
MI, MIRBuilder);
811 case TargetOpcode::G_SPLAT_VECTOR:
812 return legalizeSplatVector(
MI, MIRBuilder);
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static Type * getTypeForLLT(LLT Ty, LLVMContext &C)
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
This file declares the MachineIRBuilder class.
static MachineInstrBuilder buildAllOnesMask(LLT VecTy, const SrcOp &VL, MachineIRBuilder &MIB, MachineRegisterInfo &MRI)
Creates an all ones mask suitable for masking a vector of type VecTy with vector length VL.
static LegalityPredicate typeIsLegalBoolVec(unsigned TypeIdx, std::initializer_list< LLT > BoolVecTys, const RISCVSubtarget &ST)
static LegalityPredicate typeIsScalarFPArith(unsigned TypeIdx, const RISCVSubtarget &ST)
static LegalityPredicate typeIsLegalIntOrFPVec(unsigned TypeIdx, std::initializer_list< LLT > IntOrFPVecTys, const RISCVSubtarget &ST)
static MachineInstrBuilder buildSplatPartsS64WithVL(const DstOp &Dst, const SrcOp &Passthru, Register Lo, Register Hi, Register VL, MachineIRBuilder &MIB, MachineRegisterInfo &MRI)
static MachineInstrBuilder buildSplatSplitS64WithVL(const DstOp &Dst, const SrcOp &Passthru, const SrcOp &Scalar, Register VL, MachineIRBuilder &MIB, MachineRegisterInfo &MRI)
static std::pair< MachineInstrBuilder, Register > buildDefaultVLOps(const DstOp &Dst, MachineIRBuilder &MIB, MachineRegisterInfo &MRI)
Gets the two common "VL" operands: an all-ones mask and the vector length.
static LLT getMaskTypeFor(LLT VecTy)
Return the type of the mask type suitable for masking the provided vector type.
This file declares the targeting of the Machinelegalizer class for RISC-V.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
APInt zext(unsigned width) const
Zero extend to a new width.
unsigned getBitWidth() const
Return the number of bits in the APInt.
APInt rotr(unsigned rotateAmt) const
Rotate right by rotateAmt.
int64_t getSExtValue() const
Get sign extended value.
This is the shared class of boolean and integer constants.
const APInt & getValue() const
Return the constant as an APInt value reference.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Abstract class that contains various methods for clients to notify about changes.
virtual void changingInstr(MachineInstr &MI)=0
This instruction is about to be mutated in some way.
virtual void changedInstr(MachineInstr &MI)=0
This instruction was mutated in some way.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
constexpr bool isScalableVector() const
Returns true if the LLT is a scalable vector.
constexpr unsigned getScalarSizeInBits() const
static constexpr LLT scalable_vector(unsigned MinNumElements, unsigned ScalarSizeInBits)
Get a low-level scalable vector of some number of elements and element width.
constexpr LLT changeElementType(LLT NewEltTy) const
If this type is a vector, return a vector with the same number of elements but the new element type.
static constexpr LLT vector(ElementCount EC, unsigned ScalarSizeInBits)
Get a low-level vector of some number of elements and element width.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isVector() const
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
constexpr ElementCount getElementCount() const
This is an important class for using LLVM in a threaded context.
void computeTables()
Compute any ancillary tables needed to quickly decide how an operation should be handled.
LegalizeRuleSet & widenScalarOrEltToNextPow2OrMinSize(unsigned TypeIdx, unsigned MinSize=0)
Widen the scalar or vector element type to the next power of two that is at least MinSize.
LegalizeRuleSet & legalFor(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list.
LegalizeRuleSet & scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx)
Change the type TypeIdx to have the same scalar size as type SameSizeIdx.
LegalizeRuleSet & libcallFor(std::initializer_list< LLT > Types)
LegalizeRuleSet & maxScalar(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at most as wide as Ty.
LegalizeRuleSet & lower()
The instruction is lowered.
LegalizeRuleSet & lowerFor(std::initializer_list< LLT > Types)
The instruction is lowered when type index 0 is any type in the given list.
LegalizeRuleSet & clampScalar(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
LegalizeRuleSet & minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx)
Widen the scalar to match the size of another.
LegalizeRuleSet & widenScalarIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Widen the scalar to the one selected by the mutation if the predicate is true.
LegalizeRuleSet & customIf(LegalityPredicate Predicate)
LegalizeRuleSet & widenScalarToNextPow2(unsigned TypeIdx, unsigned MinSize=0)
Widen the scalar to the next power of two that is at least MinSize.
LegalizeRuleSet & lowerForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is lowered when type indexes 0 and 1 are both in their respective lists.
LegalizeRuleSet & legalForTypesWithMemDesc(std::initializer_list< LegalityPredicates::TypePairAndMemDesc > TypesAndMemDesc)
The instruction is legal when type indexes 0 and 1 along with the memory size and minimum alignment i...
LegalizeRuleSet & legalIf(LegalityPredicate Predicate)
The instruction is legal if predicate is true.
LegalizeRuleSet & customFor(std::initializer_list< LLT > Types)
LegalizeResult lowerAbsToMaxNeg(MachineInstr &MI)
@ Legalized
Instruction has been legalized and the MachineFunction changed.
LegalizeResult lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
Legalize an instruction by splitting it into simpler parts, hopefully understood by the target.
GISelChangeObserver & Observer
To keep track of changes made by the LegalizerHelper.
MachineIRBuilder & MIRBuilder
Expose MIRBuilder so clients can set their own RecordInsertInstruction functions.
LegalizeResult lowerConstant(MachineInstr &MI)
LegalizeRuleSet & getActionDefinitionsBuilder(unsigned Opcode)
Get the action definition builder for the given opcode.
const LegacyLegalizerInfo & getLegacyLegalizerInfo() const
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.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Helper class to build MachineInstr.
MachineInstrBuilder buildUndef(const DstOp &Res)
Build and insert Res = IMPLICIT_DEF.
MachineInstrBuilder buildUnmerge(ArrayRef< LLT > Res, const SrcOp &Op)
Build and insert Res0, ... = G_UNMERGE_VALUES Op.
MachineInstrBuilder buildSelect(const DstOp &Res, const SrcOp &Tst, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_SELECT Tst, Op0, Op1.
MachineInstrBuilder buildMul(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_MUL Op0, Op1.
MachineInstrBuilder buildAnd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1)
Build and insert Res = G_AND Op0, Op1.
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
MachineInstrBuilder buildLShr(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
MachineInstrBuilder buildShl(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineInstrBuilder buildFrameIndex(const DstOp &Res, int Idx)
Build and insert Res = G_FRAME_INDEX Idx.
MachineInstrBuilder buildZExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ZEXT Op.
MachineRegisterInfo * getMRI()
Getter for MRI.
const DataLayout & getDataLayout() const
MachineInstrBuilder buildSplatVector(const DstOp &Res, const SrcOp &Val)
Build and insert Res = G_SPLAT_VECTOR Val.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
Representation of each machine instruction.
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI, LostDebugLocObserver &LocObserver) const override
Called for instructions with the Custom LegalizationAction.
bool legalizeIntrinsic(LegalizerHelper &Helper, MachineInstr &MI) const override
RISCVLegalizerInfo(const RISCVSubtarget &ST)
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
int getVarArgsFrameIndex() const
unsigned getRealMinVLen() const
unsigned getMaxBuildIntsCost() const
bool useConstantPoolForLargeInts() const
Wrapper class representing virtual and physical registers.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
LegalityPredicate typeInSet(unsigned TypeIdx, std::initializer_list< LLT > TypesInit)
True iff the given type index is one of the specified types.
Predicate any(Predicate P0, Predicate P1)
True iff P0 or P1 are true.
Predicate all(Predicate P0, Predicate P1)
True iff P0 and P1 are true.
LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit)
True iff the given type index is the specified type.
LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty)
Select this specific type for the given type index.
InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI)
InstSeq generateTwoRegInstSeq(int64_t Val, const MCSubtargetInfo &STI, unsigned &ShiftAmt, unsigned &AddOpc)
static constexpr unsigned RVVBitsPerBlock
This is an optimization pass for GlobalISel generic memory operations.
bool isAllOnesOrAllOnesSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowUndefs=false)
Return true if the value is a constant -1 integer or a splatted vector of a constant -1 integer (with...
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
bool isNullOrNullSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowUndefs=false)
Return true if the value is a constant 0 integer or a splatted vector of a constant 0 integer (with n...
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
@ And
Bitwise or logical AND of integers.
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...
unsigned Log2(Align A)
Returns the log2 of the alignment.
std::function< bool(const LegalityQuery &)> LegalityPredicate
This struct is a compact representation of a valid (non-zero power of two) alignment.
The LegalityQuery object bundles together all the information that's needed to decide whether a given...
This class contains a discriminated union of information about pointers in memory operands,...