31 TargetOpcode::G_STRICT_FADD,
34 TargetOpcode::G_STRICT_FSUB,
37 TargetOpcode::G_STRICT_FMUL,
41 TargetOpcode::G_STRICT_FDIV,
45 TargetOpcode::G_STRICT_FREM,
47 TargetOpcode::G_CONSTANT,
48 TargetOpcode::G_FCONSTANT,
55 TargetOpcode::G_SELECT,
56 TargetOpcode::G_EXTRACT_VECTOR_ELT,
65 return [IsExtendedInts, TypeIdx](
const LegalityQuery &Query) {
66 const LLT Ty = Query.Types[TypeIdx];
72 using namespace TargetOpcode;
75 GR = ST.getSPIRVGlobalRegistry();
113 const unsigned PSize = ST.getPointerSize();
127 auto allPtrsScalarsAndVectors = {
128 p0, p1, p2, p3, p4, p5, p6, p7, p8, p10,
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 allVectors = {v2s1, v2s8, v2s16, v2s32, v2s64, v3s1, v3s8,
134 v3s16, v3s32, v3s64, v4s1, v4s8, v4s16, v4s32,
135 v4s64, v8s1, v8s8, v8s16, v8s32, v8s64, v16s1,
136 v16s8, v16s16, v16s32, v16s64};
138 auto allScalarsAndVectors = {
139 s1, s8, s16, s32, s64, v2s1, v2s8, v2s16, v2s32, v2s64,
140 v3s1, v3s8, v3s16, v3s32, v3s64, v4s1, v4s8, v4s16, v4s32, v4s64,
141 v8s1, v8s8, v8s16, v8s32, v8s64, v16s1, v16s8, v16s16, v16s32, v16s64};
143 auto allIntScalarsAndVectors = {s8, s16, s32, s64, v2s8, v2s16,
144 v2s32, v2s64, v3s8, v3s16, v3s32, v3s64,
145 v4s8, v4s16, v4s32, v4s64, v8s8, v8s16,
146 v8s32, v8s64, v16s8, v16s16, v16s32, v16s64};
148 auto allBoolScalarsAndVectors = {s1, v2s1, v3s1, v4s1, v8s1, v16s1};
150 auto allIntScalars = {s8, s16, s32, s64};
152 auto allFloatScalars = {s16, s32, s64};
154 auto allFloatScalarsAndVectors = {
155 s16, s32, s64, v2s16, v2s32, v2s64, v3s16, v3s32, v3s64,
156 v4s16, v4s32, v4s64, v8s16, v8s32, v8s64, v16s16, v16s32, v16s64};
158 auto allFloatAndIntScalarsAndPtrs = {s8, s16, s32, s64, p0, p1, p2,
159 p3, p4, p5, p6, p7, p8, p10};
161 auto allPtrs = {p0, p1, p2, p3, p4, p5, p6, p7, p8, p10};
163 bool IsExtendedInts =
165 SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers) ||
166 ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
167 auto extendedScalarsAndVectors =
169 const LLT Ty = Query.Types[0];
172 auto extendedScalarsAndVectorsProduct = [IsExtendedInts](
174 const LLT Ty1 = Query.Types[0], Ty2 = Query.Types[1];
175 return IsExtendedInts && Ty1.
isValid() && Ty2.isValid() &&
178 auto extendedPtrsScalarsAndVectors =
180 const LLT Ty = Query.Types[0];
181 return IsExtendedInts && Ty.
isValid();
191 {G_BUILD_VECTOR, G_SHUFFLE_VECTOR, G_SPLAT_VECTOR})
196 {G_VECREDUCE_SMIN, G_VECREDUCE_SMAX, G_VECREDUCE_UMIN, G_VECREDUCE_UMAX,
197 G_VECREDUCE_ADD, G_VECREDUCE_MUL, G_VECREDUCE_FMUL, G_VECREDUCE_FMIN,
198 G_VECREDUCE_FMAX, G_VECREDUCE_FMINIMUM, G_VECREDUCE_FMAXIMUM,
199 G_VECREDUCE_OR, G_VECREDUCE_AND, G_VECREDUCE_XOR})
200 .legalFor(allVectors)
224 G_BITREVERSE, G_SADDSAT, G_UADDSAT, G_SSUBSAT,
225 G_USUBSAT, G_SCMP, G_UCMP})
226 .legalFor(allIntScalarsAndVectors)
227 .
legalIf(extendedScalarsAndVectors);
230 .legalFor(allFloatScalarsAndVectors);
236 .legalForCartesianProduct(allIntScalarsAndVectors,
237 allFloatScalarsAndVectors);
240 .legalForCartesianProduct(allFloatScalarsAndVectors,
241 allScalarsAndVectors);
245 .
legalIf(extendedScalarsAndVectorsProduct);
249 .legalForCartesianProduct(allScalarsAndVectors)
250 .
legalIf(extendedScalarsAndVectorsProduct);
254 .
legalIf(extendedPtrsScalarsAndVectors);
258 typeInSet(1, allPtrsScalarsAndVectors)));
281 typeInSet(1, allPtrsScalarsAndVectors)));
285 typeInSet(1, allFloatScalarsAndVectors)));
288 G_ATOMICRMW_MAX, G_ATOMICRMW_MIN,
289 G_ATOMICRMW_SUB, G_ATOMICRMW_XOR,
290 G_ATOMICRMW_UMAX, G_ATOMICRMW_UMIN})
291 .legalForCartesianProduct(allIntScalars, allPtrs);
294 {G_ATOMICRMW_FADD, G_ATOMICRMW_FSUB, G_ATOMICRMW_FMIN, G_ATOMICRMW_FMAX})
295 .legalForCartesianProduct(allFloatScalars, allPtrs);
305 {G_UADDO, G_SADDO, G_USUBO, G_SSUBO, G_UMULO, G_SMULO})
310 .legalForCartesianProduct(allFloatScalarsAndVectors);
351 G_INTRINSIC_ROUNDEVEN})
352 .legalFor(allFloatScalarsAndVectors);
356 allFloatScalarsAndVectors);
359 allFloatScalarsAndVectors, allIntScalarsAndVectors);
361 if (ST.canUseExtInstSet(SPIRV::InstructionSet::OpenCL_std)) {
363 {G_CTTZ, G_CTTZ_ZERO_UNDEF, G_CTLZ, G_CTLZ_ZERO_UNDEF})
364 .legalForCartesianProduct(allIntScalarsAndVectors,
365 allIntScalarsAndVectors);
372 verify(*ST.getInstrInfo());
379 Register ConvReg =
MRI.createGenericVirtualRegister(ConvTy);
391 auto Opc =
MI.getOpcode();
394 assert(Opc == TargetOpcode::G_ICMP);
396 auto &Op0 =
MI.getOperand(2);
397 auto &Op1 =
MI.getOperand(3);
404 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 *SpvType, 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
void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, const MachineFunction &MF)
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite, bool EmitIR=true)
const TargetRegisterClass * getRegClass(SPIRVType *SpvType) const
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...