181ad6265SDimitry Andric //===- SPIRVLegalizerInfo.cpp --- SPIR-V Legalization Rules ------*- C++ -*-==// 281ad6265SDimitry Andric // 381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 681ad6265SDimitry Andric // 781ad6265SDimitry Andric //===----------------------------------------------------------------------===// 881ad6265SDimitry Andric // 981ad6265SDimitry Andric // This file implements the targeting of the Machinelegalizer class for SPIR-V. 1081ad6265SDimitry Andric // 1181ad6265SDimitry Andric //===----------------------------------------------------------------------===// 1281ad6265SDimitry Andric 1381ad6265SDimitry Andric #include "SPIRVLegalizerInfo.h" 1481ad6265SDimitry Andric #include "SPIRV.h" 1581ad6265SDimitry Andric #include "SPIRVGlobalRegistry.h" 1681ad6265SDimitry Andric #include "SPIRVSubtarget.h" 1781ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 1881ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 1981ad6265SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 2081ad6265SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 2181ad6265SDimitry Andric #include "llvm/CodeGen/TargetOpcodes.h" 2281ad6265SDimitry Andric 2381ad6265SDimitry Andric using namespace llvm; 2481ad6265SDimitry Andric using namespace llvm::LegalizeActions; 2581ad6265SDimitry Andric using namespace llvm::LegalityPredicates; 2681ad6265SDimitry Andric 2781ad6265SDimitry Andric static const std::set<unsigned> TypeFoldingSupportingOpcs = { 2881ad6265SDimitry Andric TargetOpcode::G_ADD, 2981ad6265SDimitry Andric TargetOpcode::G_FADD, 3081ad6265SDimitry Andric TargetOpcode::G_SUB, 3181ad6265SDimitry Andric TargetOpcode::G_FSUB, 3281ad6265SDimitry Andric TargetOpcode::G_MUL, 3381ad6265SDimitry Andric TargetOpcode::G_FMUL, 3481ad6265SDimitry Andric TargetOpcode::G_SDIV, 3581ad6265SDimitry Andric TargetOpcode::G_UDIV, 3681ad6265SDimitry Andric TargetOpcode::G_FDIV, 3781ad6265SDimitry Andric TargetOpcode::G_SREM, 3881ad6265SDimitry Andric TargetOpcode::G_UREM, 3981ad6265SDimitry Andric TargetOpcode::G_FREM, 4081ad6265SDimitry Andric TargetOpcode::G_FNEG, 4181ad6265SDimitry Andric TargetOpcode::G_CONSTANT, 4281ad6265SDimitry Andric TargetOpcode::G_FCONSTANT, 4381ad6265SDimitry Andric TargetOpcode::G_AND, 4481ad6265SDimitry Andric TargetOpcode::G_OR, 4581ad6265SDimitry Andric TargetOpcode::G_XOR, 4681ad6265SDimitry Andric TargetOpcode::G_SHL, 4781ad6265SDimitry Andric TargetOpcode::G_ASHR, 4881ad6265SDimitry Andric TargetOpcode::G_LSHR, 4981ad6265SDimitry Andric TargetOpcode::G_SELECT, 5081ad6265SDimitry Andric TargetOpcode::G_EXTRACT_VECTOR_ELT, 5181ad6265SDimitry Andric }; 5281ad6265SDimitry Andric 5381ad6265SDimitry Andric bool isTypeFoldingSupported(unsigned Opcode) { 5481ad6265SDimitry Andric return TypeFoldingSupportingOpcs.count(Opcode) > 0; 5581ad6265SDimitry Andric } 5681ad6265SDimitry Andric 5781ad6265SDimitry Andric SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) { 5881ad6265SDimitry Andric using namespace TargetOpcode; 5981ad6265SDimitry Andric 6081ad6265SDimitry Andric this->ST = &ST; 6181ad6265SDimitry Andric GR = ST.getSPIRVGlobalRegistry(); 6281ad6265SDimitry Andric 6381ad6265SDimitry Andric const LLT s1 = LLT::scalar(1); 6481ad6265SDimitry Andric const LLT s8 = LLT::scalar(8); 6581ad6265SDimitry Andric const LLT s16 = LLT::scalar(16); 6681ad6265SDimitry Andric const LLT s32 = LLT::scalar(32); 6781ad6265SDimitry Andric const LLT s64 = LLT::scalar(64); 6881ad6265SDimitry Andric 6981ad6265SDimitry Andric const LLT v16s64 = LLT::fixed_vector(16, 64); 7081ad6265SDimitry Andric const LLT v16s32 = LLT::fixed_vector(16, 32); 7181ad6265SDimitry Andric const LLT v16s16 = LLT::fixed_vector(16, 16); 7281ad6265SDimitry Andric const LLT v16s8 = LLT::fixed_vector(16, 8); 7381ad6265SDimitry Andric const LLT v16s1 = LLT::fixed_vector(16, 1); 7481ad6265SDimitry Andric 7581ad6265SDimitry Andric const LLT v8s64 = LLT::fixed_vector(8, 64); 7681ad6265SDimitry Andric const LLT v8s32 = LLT::fixed_vector(8, 32); 7781ad6265SDimitry Andric const LLT v8s16 = LLT::fixed_vector(8, 16); 7881ad6265SDimitry Andric const LLT v8s8 = LLT::fixed_vector(8, 8); 7981ad6265SDimitry Andric const LLT v8s1 = LLT::fixed_vector(8, 1); 8081ad6265SDimitry Andric 8181ad6265SDimitry Andric const LLT v4s64 = LLT::fixed_vector(4, 64); 8281ad6265SDimitry Andric const LLT v4s32 = LLT::fixed_vector(4, 32); 8381ad6265SDimitry Andric const LLT v4s16 = LLT::fixed_vector(4, 16); 8481ad6265SDimitry Andric const LLT v4s8 = LLT::fixed_vector(4, 8); 8581ad6265SDimitry Andric const LLT v4s1 = LLT::fixed_vector(4, 1); 8681ad6265SDimitry Andric 8781ad6265SDimitry Andric const LLT v3s64 = LLT::fixed_vector(3, 64); 8881ad6265SDimitry Andric const LLT v3s32 = LLT::fixed_vector(3, 32); 8981ad6265SDimitry Andric const LLT v3s16 = LLT::fixed_vector(3, 16); 9081ad6265SDimitry Andric const LLT v3s8 = LLT::fixed_vector(3, 8); 9181ad6265SDimitry Andric const LLT v3s1 = LLT::fixed_vector(3, 1); 9281ad6265SDimitry Andric 9381ad6265SDimitry Andric const LLT v2s64 = LLT::fixed_vector(2, 64); 9481ad6265SDimitry Andric const LLT v2s32 = LLT::fixed_vector(2, 32); 9581ad6265SDimitry Andric const LLT v2s16 = LLT::fixed_vector(2, 16); 9681ad6265SDimitry Andric const LLT v2s8 = LLT::fixed_vector(2, 8); 9781ad6265SDimitry Andric const LLT v2s1 = LLT::fixed_vector(2, 1); 9881ad6265SDimitry Andric 9981ad6265SDimitry Andric const unsigned PSize = ST.getPointerSize(); 10081ad6265SDimitry Andric const LLT p0 = LLT::pointer(0, PSize); // Function 10181ad6265SDimitry Andric const LLT p1 = LLT::pointer(1, PSize); // CrossWorkgroup 10281ad6265SDimitry Andric const LLT p2 = LLT::pointer(2, PSize); // UniformConstant 10381ad6265SDimitry Andric const LLT p3 = LLT::pointer(3, PSize); // Workgroup 10481ad6265SDimitry Andric const LLT p4 = LLT::pointer(4, PSize); // Generic 10581ad6265SDimitry Andric const LLT p5 = LLT::pointer(5, PSize); // Input 10681ad6265SDimitry Andric 10781ad6265SDimitry Andric // TODO: remove copy-pasting here by using concatenation in some way. 10881ad6265SDimitry Andric auto allPtrsScalarsAndVectors = { 10981ad6265SDimitry Andric p0, p1, p2, p3, p4, p5, s1, s8, s16, 11081ad6265SDimitry Andric s32, s64, v2s1, v2s8, v2s16, v2s32, v2s64, v3s1, v3s8, 11181ad6265SDimitry Andric v3s16, v3s32, v3s64, v4s1, v4s8, v4s16, v4s32, v4s64, v8s1, 11281ad6265SDimitry Andric v8s8, v8s16, v8s32, v8s64, v16s1, v16s8, v16s16, v16s32, v16s64}; 11381ad6265SDimitry Andric 11481ad6265SDimitry Andric auto allScalarsAndVectors = { 11581ad6265SDimitry Andric s1, s8, s16, s32, s64, v2s1, v2s8, v2s16, v2s32, v2s64, 11681ad6265SDimitry Andric v3s1, v3s8, v3s16, v3s32, v3s64, v4s1, v4s8, v4s16, v4s32, v4s64, 11781ad6265SDimitry Andric v8s1, v8s8, v8s16, v8s32, v8s64, v16s1, v16s8, v16s16, v16s32, v16s64}; 11881ad6265SDimitry Andric 11981ad6265SDimitry Andric auto allIntScalarsAndVectors = {s8, s16, s32, s64, v2s8, v2s16, 12081ad6265SDimitry Andric v2s32, v2s64, v3s8, v3s16, v3s32, v3s64, 12181ad6265SDimitry Andric v4s8, v4s16, v4s32, v4s64, v8s8, v8s16, 12281ad6265SDimitry Andric v8s32, v8s64, v16s8, v16s16, v16s32, v16s64}; 12381ad6265SDimitry Andric 12481ad6265SDimitry Andric auto allBoolScalarsAndVectors = {s1, v2s1, v3s1, v4s1, v8s1, v16s1}; 12581ad6265SDimitry Andric 12681ad6265SDimitry Andric auto allIntScalars = {s8, s16, s32, s64}; 12781ad6265SDimitry Andric 12881ad6265SDimitry Andric auto allFloatScalarsAndVectors = { 12981ad6265SDimitry Andric s16, s32, s64, v2s16, v2s32, v2s64, v3s16, v3s32, v3s64, 13081ad6265SDimitry Andric v4s16, v4s32, v4s64, v8s16, v8s32, v8s64, v16s16, v16s32, v16s64}; 13181ad6265SDimitry Andric 13281ad6265SDimitry Andric auto allFloatAndIntScalars = allIntScalars; 13381ad6265SDimitry Andric 13481ad6265SDimitry Andric auto allPtrs = {p0, p1, p2, p3, p4, p5}; 13581ad6265SDimitry Andric auto allWritablePtrs = {p0, p1, p3, p4}; 13681ad6265SDimitry Andric 13781ad6265SDimitry Andric for (auto Opc : TypeFoldingSupportingOpcs) 13881ad6265SDimitry Andric getActionDefinitionsBuilder(Opc).custom(); 13981ad6265SDimitry Andric 14081ad6265SDimitry Andric getActionDefinitionsBuilder(G_GLOBAL_VALUE).alwaysLegal(); 14181ad6265SDimitry Andric 14281ad6265SDimitry Andric // TODO: add proper rules for vectors legalization. 14381ad6265SDimitry Andric getActionDefinitionsBuilder({G_BUILD_VECTOR, G_SHUFFLE_VECTOR}).alwaysLegal(); 14481ad6265SDimitry Andric 14581ad6265SDimitry Andric getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE}) 14681ad6265SDimitry Andric .legalIf(all(typeInSet(0, allWritablePtrs), typeInSet(1, allPtrs))); 14781ad6265SDimitry Andric 148*bdd1243dSDimitry Andric getActionDefinitionsBuilder(G_MEMSET).legalIf( 149*bdd1243dSDimitry Andric all(typeInSet(0, allWritablePtrs), typeInSet(1, allIntScalars))); 150*bdd1243dSDimitry Andric 15181ad6265SDimitry Andric getActionDefinitionsBuilder(G_ADDRSPACE_CAST) 15281ad6265SDimitry Andric .legalForCartesianProduct(allPtrs, allPtrs); 15381ad6265SDimitry Andric 15481ad6265SDimitry Andric getActionDefinitionsBuilder({G_LOAD, G_STORE}).legalIf(typeInSet(1, allPtrs)); 15581ad6265SDimitry Andric 15681ad6265SDimitry Andric getActionDefinitionsBuilder(G_BITREVERSE).legalFor(allFloatScalarsAndVectors); 15781ad6265SDimitry Andric 15881ad6265SDimitry Andric getActionDefinitionsBuilder(G_FMA).legalFor(allFloatScalarsAndVectors); 15981ad6265SDimitry Andric 16081ad6265SDimitry Andric getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI}) 16181ad6265SDimitry Andric .legalForCartesianProduct(allIntScalarsAndVectors, 16281ad6265SDimitry Andric allFloatScalarsAndVectors); 16381ad6265SDimitry Andric 16481ad6265SDimitry Andric getActionDefinitionsBuilder({G_SITOFP, G_UITOFP}) 16581ad6265SDimitry Andric .legalForCartesianProduct(allFloatScalarsAndVectors, 16681ad6265SDimitry Andric allScalarsAndVectors); 16781ad6265SDimitry Andric 16881ad6265SDimitry Andric getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX, G_ABS}) 16981ad6265SDimitry Andric .legalFor(allIntScalarsAndVectors); 17081ad6265SDimitry Andric 17181ad6265SDimitry Andric getActionDefinitionsBuilder(G_CTPOP).legalForCartesianProduct( 17281ad6265SDimitry Andric allIntScalarsAndVectors, allIntScalarsAndVectors); 17381ad6265SDimitry Andric 17481ad6265SDimitry Andric getActionDefinitionsBuilder(G_PHI).legalFor(allPtrsScalarsAndVectors); 17581ad6265SDimitry Andric 17681ad6265SDimitry Andric getActionDefinitionsBuilder(G_BITCAST).legalIf(all( 17781ad6265SDimitry Andric typeInSet(0, allPtrsScalarsAndVectors), 17881ad6265SDimitry Andric typeInSet(1, allPtrsScalarsAndVectors), 17981ad6265SDimitry Andric LegalityPredicate(([=](const LegalityQuery &Query) { 18081ad6265SDimitry Andric return Query.Types[0].getSizeInBits() == Query.Types[1].getSizeInBits(); 18181ad6265SDimitry Andric })))); 18281ad6265SDimitry Andric 18381ad6265SDimitry Andric getActionDefinitionsBuilder(G_IMPLICIT_DEF).alwaysLegal(); 18481ad6265SDimitry Andric 18581ad6265SDimitry Andric getActionDefinitionsBuilder(G_INTTOPTR) 18681ad6265SDimitry Andric .legalForCartesianProduct(allPtrs, allIntScalars); 18781ad6265SDimitry Andric getActionDefinitionsBuilder(G_PTRTOINT) 18881ad6265SDimitry Andric .legalForCartesianProduct(allIntScalars, allPtrs); 18981ad6265SDimitry Andric getActionDefinitionsBuilder(G_PTR_ADD).legalForCartesianProduct( 19081ad6265SDimitry Andric allPtrs, allIntScalars); 19181ad6265SDimitry Andric 19281ad6265SDimitry Andric // ST.canDirectlyComparePointers() for pointer args is supported in 19381ad6265SDimitry Andric // legalizeCustom(). 19481ad6265SDimitry Andric getActionDefinitionsBuilder(G_ICMP).customIf( 19581ad6265SDimitry Andric all(typeInSet(0, allBoolScalarsAndVectors), 19681ad6265SDimitry Andric typeInSet(1, allPtrsScalarsAndVectors))); 19781ad6265SDimitry Andric 19881ad6265SDimitry Andric getActionDefinitionsBuilder(G_FCMP).legalIf( 19981ad6265SDimitry Andric all(typeInSet(0, allBoolScalarsAndVectors), 20081ad6265SDimitry Andric typeInSet(1, allFloatScalarsAndVectors))); 20181ad6265SDimitry Andric 20281ad6265SDimitry Andric getActionDefinitionsBuilder({G_ATOMICRMW_OR, G_ATOMICRMW_ADD, G_ATOMICRMW_AND, 20381ad6265SDimitry Andric G_ATOMICRMW_MAX, G_ATOMICRMW_MIN, 20481ad6265SDimitry Andric G_ATOMICRMW_SUB, G_ATOMICRMW_XOR, 20581ad6265SDimitry Andric G_ATOMICRMW_UMAX, G_ATOMICRMW_UMIN}) 20681ad6265SDimitry Andric .legalForCartesianProduct(allIntScalars, allWritablePtrs); 20781ad6265SDimitry Andric 20881ad6265SDimitry Andric getActionDefinitionsBuilder(G_ATOMICRMW_XCHG) 20981ad6265SDimitry Andric .legalForCartesianProduct(allFloatAndIntScalars, allWritablePtrs); 21081ad6265SDimitry Andric 21181ad6265SDimitry Andric getActionDefinitionsBuilder(G_ATOMIC_CMPXCHG_WITH_SUCCESS).lower(); 21281ad6265SDimitry Andric // TODO: add proper legalization rules. 21381ad6265SDimitry Andric getActionDefinitionsBuilder(G_ATOMIC_CMPXCHG).alwaysLegal(); 21481ad6265SDimitry Andric 21581ad6265SDimitry Andric getActionDefinitionsBuilder({G_UADDO, G_USUBO, G_SMULO, G_UMULO}) 21681ad6265SDimitry Andric .alwaysLegal(); 21781ad6265SDimitry Andric 21881ad6265SDimitry Andric // Extensions. 21981ad6265SDimitry Andric getActionDefinitionsBuilder({G_TRUNC, G_ZEXT, G_SEXT, G_ANYEXT}) 22081ad6265SDimitry Andric .legalForCartesianProduct(allScalarsAndVectors); 22181ad6265SDimitry Andric 22281ad6265SDimitry Andric // FP conversions. 22381ad6265SDimitry Andric getActionDefinitionsBuilder({G_FPTRUNC, G_FPEXT}) 22481ad6265SDimitry Andric .legalForCartesianProduct(allFloatScalarsAndVectors); 22581ad6265SDimitry Andric 22681ad6265SDimitry Andric // Pointer-handling. 22781ad6265SDimitry Andric getActionDefinitionsBuilder(G_FRAME_INDEX).legalFor({p0}); 22881ad6265SDimitry Andric 229*bdd1243dSDimitry Andric // Control-flow. In some cases (e.g. constants) s1 may be promoted to s32. 230*bdd1243dSDimitry Andric getActionDefinitionsBuilder(G_BRCOND).legalFor({s1, s32}); 23181ad6265SDimitry Andric 23281ad6265SDimitry Andric getActionDefinitionsBuilder({G_FPOW, 23381ad6265SDimitry Andric G_FEXP, 23481ad6265SDimitry Andric G_FEXP2, 23581ad6265SDimitry Andric G_FLOG, 23681ad6265SDimitry Andric G_FLOG2, 23781ad6265SDimitry Andric G_FABS, 23881ad6265SDimitry Andric G_FMINNUM, 23981ad6265SDimitry Andric G_FMAXNUM, 24081ad6265SDimitry Andric G_FCEIL, 24181ad6265SDimitry Andric G_FCOS, 24281ad6265SDimitry Andric G_FSIN, 24381ad6265SDimitry Andric G_FSQRT, 24481ad6265SDimitry Andric G_FFLOOR, 24581ad6265SDimitry Andric G_FRINT, 24681ad6265SDimitry Andric G_FNEARBYINT, 24781ad6265SDimitry Andric G_INTRINSIC_ROUND, 24881ad6265SDimitry Andric G_INTRINSIC_TRUNC, 24981ad6265SDimitry Andric G_FMINIMUM, 25081ad6265SDimitry Andric G_FMAXIMUM, 25181ad6265SDimitry Andric G_INTRINSIC_ROUNDEVEN}) 25281ad6265SDimitry Andric .legalFor(allFloatScalarsAndVectors); 25381ad6265SDimitry Andric 25481ad6265SDimitry Andric getActionDefinitionsBuilder(G_FCOPYSIGN) 25581ad6265SDimitry Andric .legalForCartesianProduct(allFloatScalarsAndVectors, 25681ad6265SDimitry Andric allFloatScalarsAndVectors); 25781ad6265SDimitry Andric 25881ad6265SDimitry Andric getActionDefinitionsBuilder(G_FPOWI).legalForCartesianProduct( 25981ad6265SDimitry Andric allFloatScalarsAndVectors, allIntScalarsAndVectors); 26081ad6265SDimitry Andric 261*bdd1243dSDimitry Andric if (ST.canUseExtInstSet(SPIRV::InstructionSet::OpenCL_std)) { 262*bdd1243dSDimitry Andric getActionDefinitionsBuilder(G_FLOG10).legalFor(allFloatScalarsAndVectors); 263*bdd1243dSDimitry Andric 264*bdd1243dSDimitry Andric getActionDefinitionsBuilder( 265*bdd1243dSDimitry Andric {G_CTTZ, G_CTTZ_ZERO_UNDEF, G_CTLZ, G_CTLZ_ZERO_UNDEF}) 266*bdd1243dSDimitry Andric .legalForCartesianProduct(allIntScalarsAndVectors, 267*bdd1243dSDimitry Andric allIntScalarsAndVectors); 268*bdd1243dSDimitry Andric 269*bdd1243dSDimitry Andric // Struct return types become a single scalar, so cannot easily legalize. 270*bdd1243dSDimitry Andric getActionDefinitionsBuilder({G_SMULH, G_UMULH}).alwaysLegal(); 271*bdd1243dSDimitry Andric } 272*bdd1243dSDimitry Andric 27381ad6265SDimitry Andric getLegacyLegalizerInfo().computeTables(); 27481ad6265SDimitry Andric verify(*ST.getInstrInfo()); 27581ad6265SDimitry Andric } 27681ad6265SDimitry Andric 27781ad6265SDimitry Andric static Register convertPtrToInt(Register Reg, LLT ConvTy, SPIRVType *SpirvType, 27881ad6265SDimitry Andric LegalizerHelper &Helper, 27981ad6265SDimitry Andric MachineRegisterInfo &MRI, 28081ad6265SDimitry Andric SPIRVGlobalRegistry *GR) { 28181ad6265SDimitry Andric Register ConvReg = MRI.createGenericVirtualRegister(ConvTy); 28281ad6265SDimitry Andric GR->assignSPIRVTypeToVReg(SpirvType, ConvReg, Helper.MIRBuilder.getMF()); 28381ad6265SDimitry Andric Helper.MIRBuilder.buildInstr(TargetOpcode::G_PTRTOINT) 28481ad6265SDimitry Andric .addDef(ConvReg) 28581ad6265SDimitry Andric .addUse(Reg); 28681ad6265SDimitry Andric return ConvReg; 28781ad6265SDimitry Andric } 28881ad6265SDimitry Andric 28981ad6265SDimitry Andric bool SPIRVLegalizerInfo::legalizeCustom(LegalizerHelper &Helper, 29081ad6265SDimitry Andric MachineInstr &MI) const { 29181ad6265SDimitry Andric auto Opc = MI.getOpcode(); 29281ad6265SDimitry Andric MachineRegisterInfo &MRI = MI.getMF()->getRegInfo(); 29381ad6265SDimitry Andric if (!isTypeFoldingSupported(Opc)) { 29481ad6265SDimitry Andric assert(Opc == TargetOpcode::G_ICMP); 29581ad6265SDimitry Andric assert(GR->getSPIRVTypeForVReg(MI.getOperand(0).getReg())); 29681ad6265SDimitry Andric auto &Op0 = MI.getOperand(2); 29781ad6265SDimitry Andric auto &Op1 = MI.getOperand(3); 29881ad6265SDimitry Andric Register Reg0 = Op0.getReg(); 29981ad6265SDimitry Andric Register Reg1 = Op1.getReg(); 30081ad6265SDimitry Andric CmpInst::Predicate Cond = 30181ad6265SDimitry Andric static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()); 30281ad6265SDimitry Andric if ((!ST->canDirectlyComparePointers() || 30381ad6265SDimitry Andric (Cond != CmpInst::ICMP_EQ && Cond != CmpInst::ICMP_NE)) && 30481ad6265SDimitry Andric MRI.getType(Reg0).isPointer() && MRI.getType(Reg1).isPointer()) { 30581ad6265SDimitry Andric LLT ConvT = LLT::scalar(ST->getPointerSize()); 30681ad6265SDimitry Andric Type *LLVMTy = IntegerType::get(MI.getMF()->getFunction().getContext(), 30781ad6265SDimitry Andric ST->getPointerSize()); 30881ad6265SDimitry Andric SPIRVType *SpirvTy = GR->getOrCreateSPIRVType(LLVMTy, Helper.MIRBuilder); 30981ad6265SDimitry Andric Op0.setReg(convertPtrToInt(Reg0, ConvT, SpirvTy, Helper, MRI, GR)); 31081ad6265SDimitry Andric Op1.setReg(convertPtrToInt(Reg1, ConvT, SpirvTy, Helper, MRI, GR)); 31181ad6265SDimitry Andric } 31281ad6265SDimitry Andric return true; 31381ad6265SDimitry Andric } 31481ad6265SDimitry Andric // TODO: implement legalization for other opcodes. 31581ad6265SDimitry Andric return true; 31681ad6265SDimitry Andric } 317