xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
1*81ad6265SDimitry Andric //===- SPIRVLegalizerInfo.cpp --- SPIR-V Legalization Rules ------*- C++ -*-==//
2*81ad6265SDimitry Andric //
3*81ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*81ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*81ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*81ad6265SDimitry Andric //
7*81ad6265SDimitry Andric //===----------------------------------------------------------------------===//
8*81ad6265SDimitry Andric //
9*81ad6265SDimitry Andric // This file implements the targeting of the Machinelegalizer class for SPIR-V.
10*81ad6265SDimitry Andric //
11*81ad6265SDimitry Andric //===----------------------------------------------------------------------===//
12*81ad6265SDimitry Andric 
13*81ad6265SDimitry Andric #include "SPIRVLegalizerInfo.h"
14*81ad6265SDimitry Andric #include "SPIRV.h"
15*81ad6265SDimitry Andric #include "SPIRVGlobalRegistry.h"
16*81ad6265SDimitry Andric #include "SPIRVSubtarget.h"
17*81ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
18*81ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
19*81ad6265SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
20*81ad6265SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
21*81ad6265SDimitry Andric #include "llvm/CodeGen/TargetOpcodes.h"
22*81ad6265SDimitry Andric 
23*81ad6265SDimitry Andric using namespace llvm;
24*81ad6265SDimitry Andric using namespace llvm::LegalizeActions;
25*81ad6265SDimitry Andric using namespace llvm::LegalityPredicates;
26*81ad6265SDimitry Andric 
27*81ad6265SDimitry Andric static const std::set<unsigned> TypeFoldingSupportingOpcs = {
28*81ad6265SDimitry Andric     TargetOpcode::G_ADD,
29*81ad6265SDimitry Andric     TargetOpcode::G_FADD,
30*81ad6265SDimitry Andric     TargetOpcode::G_SUB,
31*81ad6265SDimitry Andric     TargetOpcode::G_FSUB,
32*81ad6265SDimitry Andric     TargetOpcode::G_MUL,
33*81ad6265SDimitry Andric     TargetOpcode::G_FMUL,
34*81ad6265SDimitry Andric     TargetOpcode::G_SDIV,
35*81ad6265SDimitry Andric     TargetOpcode::G_UDIV,
36*81ad6265SDimitry Andric     TargetOpcode::G_FDIV,
37*81ad6265SDimitry Andric     TargetOpcode::G_SREM,
38*81ad6265SDimitry Andric     TargetOpcode::G_UREM,
39*81ad6265SDimitry Andric     TargetOpcode::G_FREM,
40*81ad6265SDimitry Andric     TargetOpcode::G_FNEG,
41*81ad6265SDimitry Andric     TargetOpcode::G_CONSTANT,
42*81ad6265SDimitry Andric     TargetOpcode::G_FCONSTANT,
43*81ad6265SDimitry Andric     TargetOpcode::G_AND,
44*81ad6265SDimitry Andric     TargetOpcode::G_OR,
45*81ad6265SDimitry Andric     TargetOpcode::G_XOR,
46*81ad6265SDimitry Andric     TargetOpcode::G_SHL,
47*81ad6265SDimitry Andric     TargetOpcode::G_ASHR,
48*81ad6265SDimitry Andric     TargetOpcode::G_LSHR,
49*81ad6265SDimitry Andric     TargetOpcode::G_SELECT,
50*81ad6265SDimitry Andric     TargetOpcode::G_EXTRACT_VECTOR_ELT,
51*81ad6265SDimitry Andric };
52*81ad6265SDimitry Andric 
53*81ad6265SDimitry Andric bool isTypeFoldingSupported(unsigned Opcode) {
54*81ad6265SDimitry Andric   return TypeFoldingSupportingOpcs.count(Opcode) > 0;
55*81ad6265SDimitry Andric }
56*81ad6265SDimitry Andric 
57*81ad6265SDimitry Andric SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
58*81ad6265SDimitry Andric   using namespace TargetOpcode;
59*81ad6265SDimitry Andric 
60*81ad6265SDimitry Andric   this->ST = &ST;
61*81ad6265SDimitry Andric   GR = ST.getSPIRVGlobalRegistry();
62*81ad6265SDimitry Andric 
63*81ad6265SDimitry Andric   const LLT s1 = LLT::scalar(1);
64*81ad6265SDimitry Andric   const LLT s8 = LLT::scalar(8);
65*81ad6265SDimitry Andric   const LLT s16 = LLT::scalar(16);
66*81ad6265SDimitry Andric   const LLT s32 = LLT::scalar(32);
67*81ad6265SDimitry Andric   const LLT s64 = LLT::scalar(64);
68*81ad6265SDimitry Andric 
69*81ad6265SDimitry Andric   const LLT v16s64 = LLT::fixed_vector(16, 64);
70*81ad6265SDimitry Andric   const LLT v16s32 = LLT::fixed_vector(16, 32);
71*81ad6265SDimitry Andric   const LLT v16s16 = LLT::fixed_vector(16, 16);
72*81ad6265SDimitry Andric   const LLT v16s8 = LLT::fixed_vector(16, 8);
73*81ad6265SDimitry Andric   const LLT v16s1 = LLT::fixed_vector(16, 1);
74*81ad6265SDimitry Andric 
75*81ad6265SDimitry Andric   const LLT v8s64 = LLT::fixed_vector(8, 64);
76*81ad6265SDimitry Andric   const LLT v8s32 = LLT::fixed_vector(8, 32);
77*81ad6265SDimitry Andric   const LLT v8s16 = LLT::fixed_vector(8, 16);
78*81ad6265SDimitry Andric   const LLT v8s8 = LLT::fixed_vector(8, 8);
79*81ad6265SDimitry Andric   const LLT v8s1 = LLT::fixed_vector(8, 1);
80*81ad6265SDimitry Andric 
81*81ad6265SDimitry Andric   const LLT v4s64 = LLT::fixed_vector(4, 64);
82*81ad6265SDimitry Andric   const LLT v4s32 = LLT::fixed_vector(4, 32);
83*81ad6265SDimitry Andric   const LLT v4s16 = LLT::fixed_vector(4, 16);
84*81ad6265SDimitry Andric   const LLT v4s8 = LLT::fixed_vector(4, 8);
85*81ad6265SDimitry Andric   const LLT v4s1 = LLT::fixed_vector(4, 1);
86*81ad6265SDimitry Andric 
87*81ad6265SDimitry Andric   const LLT v3s64 = LLT::fixed_vector(3, 64);
88*81ad6265SDimitry Andric   const LLT v3s32 = LLT::fixed_vector(3, 32);
89*81ad6265SDimitry Andric   const LLT v3s16 = LLT::fixed_vector(3, 16);
90*81ad6265SDimitry Andric   const LLT v3s8 = LLT::fixed_vector(3, 8);
91*81ad6265SDimitry Andric   const LLT v3s1 = LLT::fixed_vector(3, 1);
92*81ad6265SDimitry Andric 
93*81ad6265SDimitry Andric   const LLT v2s64 = LLT::fixed_vector(2, 64);
94*81ad6265SDimitry Andric   const LLT v2s32 = LLT::fixed_vector(2, 32);
95*81ad6265SDimitry Andric   const LLT v2s16 = LLT::fixed_vector(2, 16);
96*81ad6265SDimitry Andric   const LLT v2s8 = LLT::fixed_vector(2, 8);
97*81ad6265SDimitry Andric   const LLT v2s1 = LLT::fixed_vector(2, 1);
98*81ad6265SDimitry Andric 
99*81ad6265SDimitry Andric   const unsigned PSize = ST.getPointerSize();
100*81ad6265SDimitry Andric   const LLT p0 = LLT::pointer(0, PSize); // Function
101*81ad6265SDimitry Andric   const LLT p1 = LLT::pointer(1, PSize); // CrossWorkgroup
102*81ad6265SDimitry Andric   const LLT p2 = LLT::pointer(2, PSize); // UniformConstant
103*81ad6265SDimitry Andric   const LLT p3 = LLT::pointer(3, PSize); // Workgroup
104*81ad6265SDimitry Andric   const LLT p4 = LLT::pointer(4, PSize); // Generic
105*81ad6265SDimitry Andric   const LLT p5 = LLT::pointer(5, PSize); // Input
106*81ad6265SDimitry Andric 
107*81ad6265SDimitry Andric   // TODO: remove copy-pasting here by using concatenation in some way.
108*81ad6265SDimitry Andric   auto allPtrsScalarsAndVectors = {
109*81ad6265SDimitry Andric       p0,    p1,    p2,    p3,    p4,    p5,    s1,     s8,     s16,
110*81ad6265SDimitry Andric       s32,   s64,   v2s1,  v2s8,  v2s16, v2s32, v2s64,  v3s1,   v3s8,
111*81ad6265SDimitry Andric       v3s16, v3s32, v3s64, v4s1,  v4s8,  v4s16, v4s32,  v4s64,  v8s1,
112*81ad6265SDimitry Andric       v8s8,  v8s16, v8s32, v8s64, v16s1, v16s8, v16s16, v16s32, v16s64};
113*81ad6265SDimitry Andric 
114*81ad6265SDimitry Andric   auto allScalarsAndVectors = {
115*81ad6265SDimitry Andric       s1,   s8,   s16,   s32,   s64,   v2s1,  v2s8,  v2s16,  v2s32,  v2s64,
116*81ad6265SDimitry Andric       v3s1, v3s8, v3s16, v3s32, v3s64, v4s1,  v4s8,  v4s16,  v4s32,  v4s64,
117*81ad6265SDimitry Andric       v8s1, v8s8, v8s16, v8s32, v8s64, v16s1, v16s8, v16s16, v16s32, v16s64};
118*81ad6265SDimitry Andric 
119*81ad6265SDimitry Andric   auto allIntScalarsAndVectors = {s8,    s16,   s32,   s64,    v2s8,   v2s16,
120*81ad6265SDimitry Andric                                   v2s32, v2s64, v3s8,  v3s16,  v3s32,  v3s64,
121*81ad6265SDimitry Andric                                   v4s8,  v4s16, v4s32, v4s64,  v8s8,   v8s16,
122*81ad6265SDimitry Andric                                   v8s32, v8s64, v16s8, v16s16, v16s32, v16s64};
123*81ad6265SDimitry Andric 
124*81ad6265SDimitry Andric   auto allBoolScalarsAndVectors = {s1, v2s1, v3s1, v4s1, v8s1, v16s1};
125*81ad6265SDimitry Andric 
126*81ad6265SDimitry Andric   auto allIntScalars = {s8, s16, s32, s64};
127*81ad6265SDimitry Andric 
128*81ad6265SDimitry Andric   auto allFloatScalarsAndVectors = {
129*81ad6265SDimitry Andric       s16,   s32,   s64,   v2s16, v2s32, v2s64, v3s16,  v3s32,  v3s64,
130*81ad6265SDimitry Andric       v4s16, v4s32, v4s64, v8s16, v8s32, v8s64, v16s16, v16s32, v16s64};
131*81ad6265SDimitry Andric 
132*81ad6265SDimitry Andric   auto allFloatAndIntScalars = allIntScalars;
133*81ad6265SDimitry Andric 
134*81ad6265SDimitry Andric   auto allPtrs = {p0, p1, p2, p3, p4, p5};
135*81ad6265SDimitry Andric   auto allWritablePtrs = {p0, p1, p3, p4};
136*81ad6265SDimitry Andric 
137*81ad6265SDimitry Andric   for (auto Opc : TypeFoldingSupportingOpcs)
138*81ad6265SDimitry Andric     getActionDefinitionsBuilder(Opc).custom();
139*81ad6265SDimitry Andric 
140*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_GLOBAL_VALUE).alwaysLegal();
141*81ad6265SDimitry Andric 
142*81ad6265SDimitry Andric   // TODO: add proper rules for vectors legalization.
143*81ad6265SDimitry Andric   getActionDefinitionsBuilder({G_BUILD_VECTOR, G_SHUFFLE_VECTOR}).alwaysLegal();
144*81ad6265SDimitry Andric 
145*81ad6265SDimitry Andric   getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE})
146*81ad6265SDimitry Andric       .legalIf(all(typeInSet(0, allWritablePtrs), typeInSet(1, allPtrs)));
147*81ad6265SDimitry Andric 
148*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_ADDRSPACE_CAST)
149*81ad6265SDimitry Andric       .legalForCartesianProduct(allPtrs, allPtrs);
150*81ad6265SDimitry Andric 
151*81ad6265SDimitry Andric   getActionDefinitionsBuilder({G_LOAD, G_STORE}).legalIf(typeInSet(1, allPtrs));
152*81ad6265SDimitry Andric 
153*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_BITREVERSE).legalFor(allFloatScalarsAndVectors);
154*81ad6265SDimitry Andric 
155*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_FMA).legalFor(allFloatScalarsAndVectors);
156*81ad6265SDimitry Andric 
157*81ad6265SDimitry Andric   getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
158*81ad6265SDimitry Andric       .legalForCartesianProduct(allIntScalarsAndVectors,
159*81ad6265SDimitry Andric                                 allFloatScalarsAndVectors);
160*81ad6265SDimitry Andric 
161*81ad6265SDimitry Andric   getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
162*81ad6265SDimitry Andric       .legalForCartesianProduct(allFloatScalarsAndVectors,
163*81ad6265SDimitry Andric                                 allScalarsAndVectors);
164*81ad6265SDimitry Andric 
165*81ad6265SDimitry Andric   getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX, G_ABS})
166*81ad6265SDimitry Andric       .legalFor(allIntScalarsAndVectors);
167*81ad6265SDimitry Andric 
168*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_CTPOP).legalForCartesianProduct(
169*81ad6265SDimitry Andric       allIntScalarsAndVectors, allIntScalarsAndVectors);
170*81ad6265SDimitry Andric 
171*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_PHI).legalFor(allPtrsScalarsAndVectors);
172*81ad6265SDimitry Andric 
173*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_BITCAST).legalIf(all(
174*81ad6265SDimitry Andric       typeInSet(0, allPtrsScalarsAndVectors),
175*81ad6265SDimitry Andric       typeInSet(1, allPtrsScalarsAndVectors),
176*81ad6265SDimitry Andric       LegalityPredicate(([=](const LegalityQuery &Query) {
177*81ad6265SDimitry Andric         return Query.Types[0].getSizeInBits() == Query.Types[1].getSizeInBits();
178*81ad6265SDimitry Andric       }))));
179*81ad6265SDimitry Andric 
180*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_IMPLICIT_DEF).alwaysLegal();
181*81ad6265SDimitry Andric 
182*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_INTTOPTR)
183*81ad6265SDimitry Andric       .legalForCartesianProduct(allPtrs, allIntScalars);
184*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_PTRTOINT)
185*81ad6265SDimitry Andric       .legalForCartesianProduct(allIntScalars, allPtrs);
186*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_PTR_ADD).legalForCartesianProduct(
187*81ad6265SDimitry Andric       allPtrs, allIntScalars);
188*81ad6265SDimitry Andric 
189*81ad6265SDimitry Andric   // ST.canDirectlyComparePointers() for pointer args is supported in
190*81ad6265SDimitry Andric   // legalizeCustom().
191*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_ICMP).customIf(
192*81ad6265SDimitry Andric       all(typeInSet(0, allBoolScalarsAndVectors),
193*81ad6265SDimitry Andric           typeInSet(1, allPtrsScalarsAndVectors)));
194*81ad6265SDimitry Andric 
195*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_FCMP).legalIf(
196*81ad6265SDimitry Andric       all(typeInSet(0, allBoolScalarsAndVectors),
197*81ad6265SDimitry Andric           typeInSet(1, allFloatScalarsAndVectors)));
198*81ad6265SDimitry Andric 
199*81ad6265SDimitry Andric   getActionDefinitionsBuilder({G_ATOMICRMW_OR, G_ATOMICRMW_ADD, G_ATOMICRMW_AND,
200*81ad6265SDimitry Andric                                G_ATOMICRMW_MAX, G_ATOMICRMW_MIN,
201*81ad6265SDimitry Andric                                G_ATOMICRMW_SUB, G_ATOMICRMW_XOR,
202*81ad6265SDimitry Andric                                G_ATOMICRMW_UMAX, G_ATOMICRMW_UMIN})
203*81ad6265SDimitry Andric       .legalForCartesianProduct(allIntScalars, allWritablePtrs);
204*81ad6265SDimitry Andric 
205*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_ATOMICRMW_XCHG)
206*81ad6265SDimitry Andric       .legalForCartesianProduct(allFloatAndIntScalars, allWritablePtrs);
207*81ad6265SDimitry Andric 
208*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_ATOMIC_CMPXCHG_WITH_SUCCESS).lower();
209*81ad6265SDimitry Andric   // TODO: add proper legalization rules.
210*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_ATOMIC_CMPXCHG).alwaysLegal();
211*81ad6265SDimitry Andric 
212*81ad6265SDimitry Andric   getActionDefinitionsBuilder({G_UADDO, G_USUBO, G_SMULO, G_UMULO})
213*81ad6265SDimitry Andric       .alwaysLegal();
214*81ad6265SDimitry Andric 
215*81ad6265SDimitry Andric   // Extensions.
216*81ad6265SDimitry Andric   getActionDefinitionsBuilder({G_TRUNC, G_ZEXT, G_SEXT, G_ANYEXT})
217*81ad6265SDimitry Andric       .legalForCartesianProduct(allScalarsAndVectors);
218*81ad6265SDimitry Andric 
219*81ad6265SDimitry Andric   // FP conversions.
220*81ad6265SDimitry Andric   getActionDefinitionsBuilder({G_FPTRUNC, G_FPEXT})
221*81ad6265SDimitry Andric       .legalForCartesianProduct(allFloatScalarsAndVectors);
222*81ad6265SDimitry Andric 
223*81ad6265SDimitry Andric   // Pointer-handling.
224*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_FRAME_INDEX).legalFor({p0});
225*81ad6265SDimitry Andric 
226*81ad6265SDimitry Andric   // Control-flow.
227*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_BRCOND).legalFor({s1});
228*81ad6265SDimitry Andric 
229*81ad6265SDimitry Andric   getActionDefinitionsBuilder({G_FPOW,
230*81ad6265SDimitry Andric                                G_FEXP,
231*81ad6265SDimitry Andric                                G_FEXP2,
232*81ad6265SDimitry Andric                                G_FLOG,
233*81ad6265SDimitry Andric                                G_FLOG2,
234*81ad6265SDimitry Andric                                G_FABS,
235*81ad6265SDimitry Andric                                G_FMINNUM,
236*81ad6265SDimitry Andric                                G_FMAXNUM,
237*81ad6265SDimitry Andric                                G_FCEIL,
238*81ad6265SDimitry Andric                                G_FCOS,
239*81ad6265SDimitry Andric                                G_FSIN,
240*81ad6265SDimitry Andric                                G_FSQRT,
241*81ad6265SDimitry Andric                                G_FFLOOR,
242*81ad6265SDimitry Andric                                G_FRINT,
243*81ad6265SDimitry Andric                                G_FNEARBYINT,
244*81ad6265SDimitry Andric                                G_INTRINSIC_ROUND,
245*81ad6265SDimitry Andric                                G_INTRINSIC_TRUNC,
246*81ad6265SDimitry Andric                                G_FMINIMUM,
247*81ad6265SDimitry Andric                                G_FMAXIMUM,
248*81ad6265SDimitry Andric                                G_INTRINSIC_ROUNDEVEN})
249*81ad6265SDimitry Andric       .legalFor(allFloatScalarsAndVectors);
250*81ad6265SDimitry Andric 
251*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_FCOPYSIGN)
252*81ad6265SDimitry Andric       .legalForCartesianProduct(allFloatScalarsAndVectors,
253*81ad6265SDimitry Andric                                 allFloatScalarsAndVectors);
254*81ad6265SDimitry Andric 
255*81ad6265SDimitry Andric   getActionDefinitionsBuilder(G_FPOWI).legalForCartesianProduct(
256*81ad6265SDimitry Andric       allFloatScalarsAndVectors, allIntScalarsAndVectors);
257*81ad6265SDimitry Andric 
258*81ad6265SDimitry Andric   getLegacyLegalizerInfo().computeTables();
259*81ad6265SDimitry Andric   verify(*ST.getInstrInfo());
260*81ad6265SDimitry Andric }
261*81ad6265SDimitry Andric 
262*81ad6265SDimitry Andric static Register convertPtrToInt(Register Reg, LLT ConvTy, SPIRVType *SpirvType,
263*81ad6265SDimitry Andric                                 LegalizerHelper &Helper,
264*81ad6265SDimitry Andric                                 MachineRegisterInfo &MRI,
265*81ad6265SDimitry Andric                                 SPIRVGlobalRegistry *GR) {
266*81ad6265SDimitry Andric   Register ConvReg = MRI.createGenericVirtualRegister(ConvTy);
267*81ad6265SDimitry Andric   GR->assignSPIRVTypeToVReg(SpirvType, ConvReg, Helper.MIRBuilder.getMF());
268*81ad6265SDimitry Andric   Helper.MIRBuilder.buildInstr(TargetOpcode::G_PTRTOINT)
269*81ad6265SDimitry Andric       .addDef(ConvReg)
270*81ad6265SDimitry Andric       .addUse(Reg);
271*81ad6265SDimitry Andric   return ConvReg;
272*81ad6265SDimitry Andric }
273*81ad6265SDimitry Andric 
274*81ad6265SDimitry Andric bool SPIRVLegalizerInfo::legalizeCustom(LegalizerHelper &Helper,
275*81ad6265SDimitry Andric                                         MachineInstr &MI) const {
276*81ad6265SDimitry Andric   auto Opc = MI.getOpcode();
277*81ad6265SDimitry Andric   MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
278*81ad6265SDimitry Andric   if (!isTypeFoldingSupported(Opc)) {
279*81ad6265SDimitry Andric     assert(Opc == TargetOpcode::G_ICMP);
280*81ad6265SDimitry Andric     assert(GR->getSPIRVTypeForVReg(MI.getOperand(0).getReg()));
281*81ad6265SDimitry Andric     auto &Op0 = MI.getOperand(2);
282*81ad6265SDimitry Andric     auto &Op1 = MI.getOperand(3);
283*81ad6265SDimitry Andric     Register Reg0 = Op0.getReg();
284*81ad6265SDimitry Andric     Register Reg1 = Op1.getReg();
285*81ad6265SDimitry Andric     CmpInst::Predicate Cond =
286*81ad6265SDimitry Andric         static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
287*81ad6265SDimitry Andric     if ((!ST->canDirectlyComparePointers() ||
288*81ad6265SDimitry Andric          (Cond != CmpInst::ICMP_EQ && Cond != CmpInst::ICMP_NE)) &&
289*81ad6265SDimitry Andric         MRI.getType(Reg0).isPointer() && MRI.getType(Reg1).isPointer()) {
290*81ad6265SDimitry Andric       LLT ConvT = LLT::scalar(ST->getPointerSize());
291*81ad6265SDimitry Andric       Type *LLVMTy = IntegerType::get(MI.getMF()->getFunction().getContext(),
292*81ad6265SDimitry Andric                                       ST->getPointerSize());
293*81ad6265SDimitry Andric       SPIRVType *SpirvTy = GR->getOrCreateSPIRVType(LLVMTy, Helper.MIRBuilder);
294*81ad6265SDimitry Andric       Op0.setReg(convertPtrToInt(Reg0, ConvT, SpirvTy, Helper, MRI, GR));
295*81ad6265SDimitry Andric       Op1.setReg(convertPtrToInt(Reg1, ConvT, SpirvTy, Helper, MRI, GR));
296*81ad6265SDimitry Andric     }
297*81ad6265SDimitry Andric     return true;
298*81ad6265SDimitry Andric   }
299*81ad6265SDimitry Andric   // TODO: implement legalization for other opcodes.
300*81ad6265SDimitry Andric   return true;
301*81ad6265SDimitry Andric }
302