41 TargetOpcode::G_CONSTANT,
42 TargetOpcode::G_FCONSTANT,
49 TargetOpcode::G_SELECT,
50 TargetOpcode::G_EXTRACT_VECTOR_ELT,
58 return [IsExtendedInts, TypeIdx](
const LegalityQuery &Query) {
59 const LLT Ty = Query.Types[TypeIdx];
65 using namespace TargetOpcode;
68 GR = ST.getSPIRVGlobalRegistry();
106 const unsigned PSize = ST.getPointerSize();
117 auto allPtrsScalarsAndVectors = {
118 p0, p1, p2, p3, p4, p5, p6, s1, s8, s16,
119 s32, s64, v2s1, v2s8, v2s16, v2s32, v2s64, v3s1, v3s8, v3s16,
120 v3s32, v3s64, v4s1, v4s8, v4s16, v4s32, v4s64, v8s1, v8s8, v8s16,
121 v8s32, v8s64, v16s1, v16s8, v16s16, v16s32, v16s64};
123 auto allVectors = {v2s1, v2s8, v2s16, v2s32, v2s64, v3s1, v3s8,
124 v3s16, v3s32, v3s64, v4s1, v4s8, v4s16, v4s32,
125 v4s64, v8s1, v8s8, v8s16, v8s32, v8s64, v16s1,
126 v16s8, v16s16, v16s32, v16s64};
128 auto allScalarsAndVectors = {
129 s1, s8, s16, s32, s64, v2s1, v2s8, v2s16, v2s32, v2s64,
130 v3s1, v3s8, v3s16, v3s32, v3s64, v4s1, v4s8, v4s16, v4s32, v4s64,
131 v8s1, v8s8, v8s16, v8s32, v8s64, v16s1, v16s8, v16s16, v16s32, v16s64};
133 auto allIntScalarsAndVectors = {s8, s16, s32, s64, v2s8, v2s16,
134 v2s32, v2s64, v3s8, v3s16, v3s32, v3s64,
135 v4s8, v4s16, v4s32, v4s64, v8s8, v8s16,
136 v8s32, v8s64, v16s8, v16s16, v16s32, v16s64};
138 auto allBoolScalarsAndVectors = {s1, v2s1, v3s1, v4s1, v8s1, v16s1};
140 auto allIntScalars = {s8, s16, s32, s64};
142 auto allFloatScalars = {s16, s32, s64};
144 auto allFloatScalarsAndVectors = {
145 s16, s32, s64, v2s16, v2s32, v2s64, v3s16, v3s32, v3s64,
146 v4s16, v4s32, v4s64, v8s16, v8s32, v8s64, v16s16, v16s32, v16s64};
148 auto allFloatAndIntScalarsAndPtrs = {s8, s16, s32, s64, p0, p1,
151 auto allPtrs = {p0, p1, p2, p3, p4, p5, p6};
153 bool IsExtendedInts =
155 SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers) ||
156 ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
157 auto extendedScalarsAndVectors =
159 const LLT Ty = Query.Types[0];
162 auto extendedScalarsAndVectorsProduct = [IsExtendedInts](
164 const LLT Ty1 = Query.Types[0], Ty2 = Query.Types[1];
165 return IsExtendedInts && Ty1.
isValid() && Ty2.isValid() &&
168 auto extendedPtrsScalarsAndVectors =
170 const LLT Ty = Query.Types[0];
171 return IsExtendedInts && Ty.
isValid();
181 {G_BUILD_VECTOR, G_SHUFFLE_VECTOR, G_SPLAT_VECTOR})
186 {G_VECREDUCE_SMIN, G_VECREDUCE_SMAX, G_VECREDUCE_UMIN, G_VECREDUCE_UMAX,
187 G_VECREDUCE_ADD, G_VECREDUCE_MUL, G_VECREDUCE_FMUL, G_VECREDUCE_FMIN,
188 G_VECREDUCE_FMAX, G_VECREDUCE_FMINIMUM, G_VECREDUCE_FMAXIMUM,
189 G_VECREDUCE_OR, G_VECREDUCE_AND, G_VECREDUCE_XOR})
190 .legalFor(allVectors)
214 G_BITREVERSE, G_SADDSAT, G_UADDSAT, G_SSUBSAT,
216 .legalFor(allIntScalarsAndVectors)
217 .
legalIf(extendedScalarsAndVectors);
222 .legalForCartesianProduct(allIntScalarsAndVectors,
223 allFloatScalarsAndVectors);
226 .legalForCartesianProduct(allFloatScalarsAndVectors,
227 allScalarsAndVectors);
231 .
legalIf(extendedScalarsAndVectorsProduct);
235 .legalForCartesianProduct(allScalarsAndVectors)
236 .
legalIf(extendedScalarsAndVectorsProduct);
240 .
legalIf(extendedPtrsScalarsAndVectors);
244 typeInSet(1, allPtrsScalarsAndVectors)));
267 typeInSet(1, allPtrsScalarsAndVectors)));
271 typeInSet(1, allFloatScalarsAndVectors)));
274 G_ATOMICRMW_MAX, G_ATOMICRMW_MIN,
275 G_ATOMICRMW_SUB, G_ATOMICRMW_XOR,
276 G_ATOMICRMW_UMAX, G_ATOMICRMW_UMIN})
277 .legalForCartesianProduct(allIntScalars, allPtrs);
280 {G_ATOMICRMW_FADD, G_ATOMICRMW_FSUB, G_ATOMICRMW_FMIN, G_ATOMICRMW_FMAX})
281 .legalForCartesianProduct(allFloatScalars, allPtrs);
295 .legalForCartesianProduct(allFloatScalarsAndVectors);
334 G_INTRINSIC_ROUNDEVEN})
335 .legalFor(allFloatScalarsAndVectors);
339 allFloatScalarsAndVectors);
342 allFloatScalarsAndVectors, allIntScalarsAndVectors);
344 if (ST.canUseExtInstSet(SPIRV::InstructionSet::OpenCL_std)) {
346 {G_CTTZ, G_CTTZ_ZERO_UNDEF, G_CTLZ, G_CTLZ_ZERO_UNDEF})
347 .legalForCartesianProduct(allIntScalarsAndVectors,
348 allIntScalarsAndVectors);
355 verify(*ST.getInstrInfo());
362 Register ConvReg =
MRI.createGenericVirtualRegister(ConvTy);
373 auto Opc =
MI.getOpcode();
376 assert(Opc == TargetOpcode::G_ICMP);
378 auto &Op0 =
MI.getOperand(2);
379 auto &Op1 =
MI.getOperand(3);
386 MRI.getType(Reg0).isPointer() &&
MRI.getType(Reg1).isPointer()) {
unsigned const MachineRegisterInfo * MRI
static void scalarize(BinaryOperator *BO, SmallVectorImpl< BinaryOperator * > &Replace)
This file declares the MachineIRBuilder class.
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isTypeFoldingSupported(unsigned Opcode)
static const std::set< unsigned > TypeFoldingSupportingOpcs
static Register convertPtrToInt(Register Reg, LLT ConvTy, SPIRVType *SpirvType, LegalizerHelper &Helper, MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR)
bool isTypeFoldingSupported(unsigned Opcode)
LegalityPredicate typeOfExtendedScalars(unsigned TypeIdx, bool IsExtendedInts)
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
constexpr bool isScalar() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr bool isValid() const
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
constexpr bool isPointerOrPointerVector() const
void computeTables()
Compute any ancillary tables needed to quickly decide how an operation should be handled.
LegalizeRuleSet & legalFor(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list.
LegalizeRuleSet & lower()
The instruction is lowered.
LegalizeRuleSet & custom()
Unconditionally custom lower.
LegalizeRuleSet & alwaysLegal()
LegalizeRuleSet & customIf(LegalityPredicate Predicate)
LegalizeRuleSet & scalarize(unsigned TypeIdx)
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types)
The instruction is legal when type indexes 0 and 1 are both in the given list.
LegalizeRuleSet & legalIf(LegalityPredicate Predicate)
The instruction is legal if predicate is true.
MachineIRBuilder & MIRBuilder
Expose MIRBuilder so clients can set their own RecordInsertInstruction functions.
LegalizeRuleSet & getActionDefinitionsBuilder(unsigned Opcode)
Get the action definition builder for the given opcode.
const LegacyLegalizerInfo & getLegacyLegalizerInfo() const
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineFunction & getMF()
Getter for the function we currently build.
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
SPIRVType * getSPIRVTypeForVReg(Register VReg, const MachineFunction *MF=nullptr) const
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite, bool EmitIR=true)
void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, MachineFunction &MF)
SPIRVLegalizerInfo(const SPIRVSubtarget &ST)
bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI, LostDebugLocObserver &LocObserver) const override
Called for instructions with the Custom LegalizationAction.
unsigned getPointerSize() const
bool canDirectlyComparePointers() const
The instances of the Type class are immutable: once they are created, they are never changed.
LegalityPredicate typeInSet(unsigned TypeIdx, std::initializer_list< LLT > TypesInit)
True iff the given type index is one of the specified types.
Predicate all(Predicate P0, Predicate P1)
True iff P0 and P1 are true.
This is an optimization pass for GlobalISel generic memory operations.
std::function< bool(const LegalityQuery &)> LegalityPredicate
The LegalityQuery object bundles together all the information that's needed to decide whether a given...