blob: 008aecf4cda85f6df060abf51bb967cd655b7242 [file] [log] [blame]
Ilia Diachkoveab7d362022-04-14 01:11:15 +03001//===- SPIRVLegalizerInfo.cpp --- SPIR-V Legalization Rules ------*- C++ -*-==//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the targeting of the Machinelegalizer class for SPIR-V.
10//
11//===----------------------------------------------------------------------===//
12
13#include "SPIRVLegalizerInfo.h"
14#include "SPIRV.h"
15#include "SPIRVGlobalRegistry.h"
16#include "SPIRVSubtarget.h"
17#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
18#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
19#include "llvm/CodeGen/MachineInstr.h"
20#include "llvm/CodeGen/MachineRegisterInfo.h"
21#include "llvm/CodeGen/TargetOpcodes.h"
22
23using namespace llvm;
24using namespace llvm::LegalizeActions;
25using namespace llvm::LegalityPredicates;
26
Vyacheslav Levytskyy67d3ef72024-08-22 09:40:27 +020027LegalityPredicate typeOfExtendedScalars(unsigned TypeIdx, bool IsExtendedInts) {
28 return [IsExtendedInts, TypeIdx](const LegalityQuery &Query) {
29 const LLT Ty = Query.Types[TypeIdx];
30 return IsExtendedInts && Ty.isValid() && Ty.isScalar();
31 };
32}
33
Ilia Diachkoveab7d362022-04-14 01:11:15 +030034SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
35 using namespace TargetOpcode;
36
37 this->ST = &ST;
38 GR = ST.getSPIRVGlobalRegistry();
39
40 const LLT s1 = LLT::scalar(1);
41 const LLT s8 = LLT::scalar(8);
42 const LLT s16 = LLT::scalar(16);
43 const LLT s32 = LLT::scalar(32);
44 const LLT s64 = LLT::scalar(64);
45
46 const LLT v16s64 = LLT::fixed_vector(16, 64);
47 const LLT v16s32 = LLT::fixed_vector(16, 32);
48 const LLT v16s16 = LLT::fixed_vector(16, 16);
49 const LLT v16s8 = LLT::fixed_vector(16, 8);
50 const LLT v16s1 = LLT::fixed_vector(16, 1);
51
52 const LLT v8s64 = LLT::fixed_vector(8, 64);
53 const LLT v8s32 = LLT::fixed_vector(8, 32);
54 const LLT v8s16 = LLT::fixed_vector(8, 16);
55 const LLT v8s8 = LLT::fixed_vector(8, 8);
56 const LLT v8s1 = LLT::fixed_vector(8, 1);
57
58 const LLT v4s64 = LLT::fixed_vector(4, 64);
59 const LLT v4s32 = LLT::fixed_vector(4, 32);
60 const LLT v4s16 = LLT::fixed_vector(4, 16);
61 const LLT v4s8 = LLT::fixed_vector(4, 8);
62 const LLT v4s1 = LLT::fixed_vector(4, 1);
63
64 const LLT v3s64 = LLT::fixed_vector(3, 64);
65 const LLT v3s32 = LLT::fixed_vector(3, 32);
66 const LLT v3s16 = LLT::fixed_vector(3, 16);
67 const LLT v3s8 = LLT::fixed_vector(3, 8);
68 const LLT v3s1 = LLT::fixed_vector(3, 1);
69
70 const LLT v2s64 = LLT::fixed_vector(2, 64);
71 const LLT v2s32 = LLT::fixed_vector(2, 32);
72 const LLT v2s16 = LLT::fixed_vector(2, 16);
73 const LLT v2s8 = LLT::fixed_vector(2, 8);
74 const LLT v2s1 = LLT::fixed_vector(2, 1);
75
76 const unsigned PSize = ST.getPointerSize();
77 const LLT p0 = LLT::pointer(0, PSize); // Function
78 const LLT p1 = LLT::pointer(1, PSize); // CrossWorkgroup
79 const LLT p2 = LLT::pointer(2, PSize); // UniformConstant
80 const LLT p3 = LLT::pointer(3, PSize); // Workgroup
81 const LLT p4 = LLT::pointer(4, PSize); // Generic
Vyacheslav Levytskyy4a602d922024-02-22 11:05:19 +010082 const LLT p5 =
83 LLT::pointer(5, PSize); // Input, SPV_INTEL_usm_storage_classes (Device)
84 const LLT p6 = LLT::pointer(6, PSize); // SPV_INTEL_usm_storage_classes (Host)
Nathan Gauër5f99eb92024-12-03 13:42:02 +010085 const LLT p7 = LLT::pointer(7, PSize); // Input
86 const LLT p8 = LLT::pointer(8, PSize); // Output
87 const LLT p10 = LLT::pointer(10, PSize); // Private
Ilia Diachkoveab7d362022-04-14 01:11:15 +030088
89 // TODO: remove copy-pasting here by using concatenation in some way.
90 auto allPtrsScalarsAndVectors = {
Nathan Gauër5f99eb92024-12-03 13:42:02 +010091 p0, p1, p2, p3, p4, p5, p6, p7, p8, p10,
92 s1, s8, s16, s32, s64, v2s1, v2s8, v2s16, v2s32, v2s64,
93 v3s1, v3s8, v3s16, v3s32, v3s64, v4s1, v4s8, v4s16, v4s32, v4s64,
94 v8s1, v8s8, v8s16, v8s32, v8s64, v16s1, v16s8, v16s16, v16s32, v16s64};
Ilia Diachkoveab7d362022-04-14 01:11:15 +030095
Vyacheslav Levytskyy540d2552024-03-04 12:14:58 +010096 auto allVectors = {v2s1, v2s8, v2s16, v2s32, v2s64, v3s1, v3s8,
97 v3s16, v3s32, v3s64, v4s1, v4s8, v4s16, v4s32,
98 v4s64, v8s1, v8s8, v8s16, v8s32, v8s64, v16s1,
99 v16s8, v16s16, v16s32, v16s64};
100
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300101 auto allScalarsAndVectors = {
102 s1, s8, s16, s32, s64, v2s1, v2s8, v2s16, v2s32, v2s64,
103 v3s1, v3s8, v3s16, v3s32, v3s64, v4s1, v4s8, v4s16, v4s32, v4s64,
104 v8s1, v8s8, v8s16, v8s32, v8s64, v16s1, v16s8, v16s16, v16s32, v16s64};
105
106 auto allIntScalarsAndVectors = {s8, s16, s32, s64, v2s8, v2s16,
107 v2s32, v2s64, v3s8, v3s16, v3s32, v3s64,
108 v4s8, v4s16, v4s32, v4s64, v8s8, v8s16,
109 v8s32, v8s64, v16s8, v16s16, v16s32, v16s64};
110
111 auto allBoolScalarsAndVectors = {s1, v2s1, v3s1, v4s1, v8s1, v16s1};
112
113 auto allIntScalars = {s8, s16, s32, s64};
114
Vyacheslav Levytskyy925768e2024-02-19 12:12:09 +0100115 auto allFloatScalars = {s16, s32, s64};
116
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300117 auto allFloatScalarsAndVectors = {
118 s16, s32, s64, v2s16, v2s32, v2s64, v3s16, v3s32, v3s64,
119 v4s16, v4s32, v4s64, v8s16, v8s32, v8s64, v16s16, v16s32, v16s64};
120
Nathan Gauër5f99eb92024-12-03 13:42:02 +0100121 auto allFloatAndIntScalarsAndPtrs = {s8, s16, s32, s64, p0, p1, p2,
122 p3, p4, p5, p6, p7, p8, p10};
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300123
Nathan Gauër5f99eb92024-12-03 13:42:02 +0100124 auto allPtrs = {p0, p1, p2, p3, p4, p5, p6, p7, p8, p10};
Vyacheslav Levytskyy67d3ef72024-08-22 09:40:27 +0200125
126 bool IsExtendedInts =
127 ST.canUseExtension(
128 SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers) ||
129 ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
130 auto extendedScalarsAndVectors =
131 [IsExtendedInts](const LegalityQuery &Query) {
132 const LLT Ty = Query.Types[0];
133 return IsExtendedInts && Ty.isValid() && !Ty.isPointerOrPointerVector();
134 };
135 auto extendedScalarsAndVectorsProduct = [IsExtendedInts](
136 const LegalityQuery &Query) {
137 const LLT Ty1 = Query.Types[0], Ty2 = Query.Types[1];
138 return IsExtendedInts && Ty1.isValid() && Ty2.isValid() &&
139 !Ty1.isPointerOrPointerVector() && !Ty2.isPointerOrPointerVector();
140 };
141 auto extendedPtrsScalarsAndVectors =
142 [IsExtendedInts](const LegalityQuery &Query) {
143 const LLT Ty = Query.Types[0];
144 return IsExtendedInts && Ty.isValid();
145 };
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300146
Vyacheslav Levytskyy54cc4142025-03-26 17:58:10 +0100147 for (auto Opc : getTypeFoldingSupportedOpcodes())
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300148 getActionDefinitionsBuilder(Opc).custom();
149
150 getActionDefinitionsBuilder(G_GLOBAL_VALUE).alwaysLegal();
151
152 // TODO: add proper rules for vectors legalization.
Vyacheslav Levytskyy0a443f12024-03-13 08:32:01 +0100153 getActionDefinitionsBuilder(
154 {G_BUILD_VECTOR, G_SHUFFLE_VECTOR, G_SPLAT_VECTOR})
155 .alwaysLegal();
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300156
Vyacheslav Levytskyy540d2552024-03-04 12:14:58 +0100157 // Vector Reduction Operations
158 getActionDefinitionsBuilder(
159 {G_VECREDUCE_SMIN, G_VECREDUCE_SMAX, G_VECREDUCE_UMIN, G_VECREDUCE_UMAX,
160 G_VECREDUCE_ADD, G_VECREDUCE_MUL, G_VECREDUCE_FMUL, G_VECREDUCE_FMIN,
161 G_VECREDUCE_FMAX, G_VECREDUCE_FMINIMUM, G_VECREDUCE_FMAXIMUM,
162 G_VECREDUCE_OR, G_VECREDUCE_AND, G_VECREDUCE_XOR})
163 .legalFor(allVectors)
164 .scalarize(1)
165 .lower();
166
167 getActionDefinitionsBuilder({G_VECREDUCE_SEQ_FADD, G_VECREDUCE_SEQ_FMUL})
168 .scalarize(2)
169 .lower();
170
171 // Merge/Unmerge
172 // TODO: add proper legalization rules.
173 getActionDefinitionsBuilder(G_UNMERGE_VALUES).alwaysLegal();
174
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300175 getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE})
Vyacheslav Levytskyy67d3ef72024-08-22 09:40:27 +0200176 .legalIf(all(typeInSet(0, allPtrs), typeInSet(1, allPtrs)));
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300177
Ilia Diachkov3544d202022-09-14 11:51:03 +0300178 getActionDefinitionsBuilder(G_MEMSET).legalIf(
Vyacheslav Levytskyy67d3ef72024-08-22 09:40:27 +0200179 all(typeInSet(0, allPtrs), typeInSet(1, allIntScalars)));
Ilia Diachkov3544d202022-09-14 11:51:03 +0300180
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300181 getActionDefinitionsBuilder(G_ADDRSPACE_CAST)
182 .legalForCartesianProduct(allPtrs, allPtrs);
183
184 getActionDefinitionsBuilder({G_LOAD, G_STORE}).legalIf(typeInSet(1, allPtrs));
185
Vyacheslav Levytskyy67d3ef72024-08-22 09:40:27 +0200186 getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX, G_ABS,
187 G_BITREVERSE, G_SADDSAT, G_UADDSAT, G_SSUBSAT,
Vyacheslav Levytskyy0f131702024-11-28 11:10:07 +0100188 G_USUBSAT, G_SCMP, G_UCMP})
Vyacheslav Levytskyy67d3ef72024-08-22 09:40:27 +0200189 .legalFor(allIntScalarsAndVectors)
190 .legalIf(extendedScalarsAndVectors);
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300191
Vyacheslav Levytskyy978de2d2024-12-16 10:29:46 +0100192 getActionDefinitionsBuilder({G_FMA, G_STRICT_FMA})
193 .legalFor(allFloatScalarsAndVectors);
194
195 getActionDefinitionsBuilder(G_STRICT_FLDEXP)
196 .legalForCartesianProduct(allFloatScalarsAndVectors, allIntScalars);
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300197
198 getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
199 .legalForCartesianProduct(allIntScalarsAndVectors,
200 allFloatScalarsAndVectors);
201
202 getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
203 .legalForCartesianProduct(allFloatScalarsAndVectors,
204 allScalarsAndVectors);
205
Vyacheslav Levytskyy67d3ef72024-08-22 09:40:27 +0200206 getActionDefinitionsBuilder(G_CTPOP)
207 .legalForCartesianProduct(allIntScalarsAndVectors)
208 .legalIf(extendedScalarsAndVectorsProduct);
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300209
Vyacheslav Levytskyy67d3ef72024-08-22 09:40:27 +0200210 // Extensions.
211 getActionDefinitionsBuilder({G_TRUNC, G_ZEXT, G_SEXT, G_ANYEXT})
212 .legalForCartesianProduct(allScalarsAndVectors)
213 .legalIf(extendedScalarsAndVectorsProduct);
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300214
Vyacheslav Levytskyy67d3ef72024-08-22 09:40:27 +0200215 getActionDefinitionsBuilder(G_PHI)
216 .legalFor(allPtrsScalarsAndVectors)
217 .legalIf(extendedPtrsScalarsAndVectors);
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300218
Vyacheslav Levytskyyecc3bda2024-03-04 12:15:30 +0100219 getActionDefinitionsBuilder(G_BITCAST).legalIf(
220 all(typeInSet(0, allPtrsScalarsAndVectors),
221 typeInSet(1, allPtrsScalarsAndVectors)));
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300222
Vyacheslav Levytskyy9796b0e2024-02-27 10:58:04 +0100223 getActionDefinitionsBuilder({G_IMPLICIT_DEF, G_FREEZE}).alwaysLegal();
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300224
Vyacheslav Levytskyyada70f52024-02-27 10:58:45 +0100225 getActionDefinitionsBuilder({G_STACKSAVE, G_STACKRESTORE}).alwaysLegal();
226
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300227 getActionDefinitionsBuilder(G_INTTOPTR)
Vyacheslav Levytskyy67d3ef72024-08-22 09:40:27 +0200228 .legalForCartesianProduct(allPtrs, allIntScalars)
229 .legalIf(
230 all(typeInSet(0, allPtrs), typeOfExtendedScalars(1, IsExtendedInts)));
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300231 getActionDefinitionsBuilder(G_PTRTOINT)
Vyacheslav Levytskyy67d3ef72024-08-22 09:40:27 +0200232 .legalForCartesianProduct(allIntScalars, allPtrs)
233 .legalIf(
234 all(typeOfExtendedScalars(0, IsExtendedInts), typeInSet(1, allPtrs)));
235 getActionDefinitionsBuilder(G_PTR_ADD)
236 .legalForCartesianProduct(allPtrs, allIntScalars)
237 .legalIf(
238 all(typeInSet(0, allPtrs), typeOfExtendedScalars(1, IsExtendedInts)));
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300239
240 // ST.canDirectlyComparePointers() for pointer args is supported in
241 // legalizeCustom().
242 getActionDefinitionsBuilder(G_ICMP).customIf(
243 all(typeInSet(0, allBoolScalarsAndVectors),
244 typeInSet(1, allPtrsScalarsAndVectors)));
245
246 getActionDefinitionsBuilder(G_FCMP).legalIf(
247 all(typeInSet(0, allBoolScalarsAndVectors),
248 typeInSet(1, allFloatScalarsAndVectors)));
249
250 getActionDefinitionsBuilder({G_ATOMICRMW_OR, G_ATOMICRMW_ADD, G_ATOMICRMW_AND,
251 G_ATOMICRMW_MAX, G_ATOMICRMW_MIN,
252 G_ATOMICRMW_SUB, G_ATOMICRMW_XOR,
253 G_ATOMICRMW_UMAX, G_ATOMICRMW_UMIN})
Vyacheslav Levytskyy67d3ef72024-08-22 09:40:27 +0200254 .legalForCartesianProduct(allIntScalars, allPtrs);
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300255
Vyacheslav Levytskyy925768e2024-02-19 12:12:09 +0100256 getActionDefinitionsBuilder(
257 {G_ATOMICRMW_FADD, G_ATOMICRMW_FSUB, G_ATOMICRMW_FMIN, G_ATOMICRMW_FMAX})
Vyacheslav Levytskyy67d3ef72024-08-22 09:40:27 +0200258 .legalForCartesianProduct(allFloatScalars, allPtrs);
Vyacheslav Levytskyy925768e2024-02-19 12:12:09 +0100259
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300260 getActionDefinitionsBuilder(G_ATOMICRMW_XCHG)
Vyacheslav Levytskyy67d3ef72024-08-22 09:40:27 +0200261 .legalForCartesianProduct(allFloatAndIntScalarsAndPtrs, allPtrs);
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300262
263 getActionDefinitionsBuilder(G_ATOMIC_CMPXCHG_WITH_SUCCESS).lower();
264 // TODO: add proper legalization rules.
265 getActionDefinitionsBuilder(G_ATOMIC_CMPXCHG).alwaysLegal();
266
Vyacheslav Levytskyya059b292024-09-26 10:57:02 +0200267 getActionDefinitionsBuilder(
268 {G_UADDO, G_SADDO, G_USUBO, G_SSUBO, G_UMULO, G_SMULO})
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300269 .alwaysLegal();
270
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300271 // FP conversions.
272 getActionDefinitionsBuilder({G_FPTRUNC, G_FPEXT})
273 .legalForCartesianProduct(allFloatScalarsAndVectors);
274
275 // Pointer-handling.
276 getActionDefinitionsBuilder(G_FRAME_INDEX).legalFor({p0});
277
Ilia Diachkov3544d202022-09-14 11:51:03 +0300278 // Control-flow. In some cases (e.g. constants) s1 may be promoted to s32.
279 getActionDefinitionsBuilder(G_BRCOND).legalFor({s1, s32});
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300280
Natalie Chouinard0a2aaab2023-10-06 09:38:00 -0400281 // TODO: Review the target OpenCL and GLSL Extended Instruction Set specs to
282 // tighten these requirements. Many of these math functions are only legal on
283 // specific bitwidths, so they are not selectable for
284 // allFloatScalarsAndVectors.
Vyacheslav Levytskyy3ed2a812024-12-18 10:04:13 +0100285 getActionDefinitionsBuilder({G_STRICT_FSQRT,
286 G_FPOW,
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300287 G_FEXP,
288 G_FEXP2,
289 G_FLOG,
290 G_FLOG2,
Natalie Chouinard0a2aaab2023-10-06 09:38:00 -0400291 G_FLOG10,
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300292 G_FABS,
293 G_FMINNUM,
294 G_FMAXNUM,
295 G_FCEIL,
296 G_FCOS,
297 G_FSIN,
Farzon Lotfi3e824422024-05-08 00:57:39 -0400298 G_FTAN,
Farzon Lotfi2ae68892024-06-20 10:34:23 -0400299 G_FACOS,
300 G_FASIN,
301 G_FATAN,
Tex Riddell139688a2024-09-26 15:00:59 -0700302 G_FATAN2,
Farzon Lotfi2ae68892024-06-20 10:34:23 -0400303 G_FCOSH,
304 G_FSINH,
305 G_FTANH,
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300306 G_FSQRT,
307 G_FFLOOR,
308 G_FRINT,
309 G_FNEARBYINT,
310 G_INTRINSIC_ROUND,
311 G_INTRINSIC_TRUNC,
312 G_FMINIMUM,
313 G_FMAXIMUM,
314 G_INTRINSIC_ROUNDEVEN})
315 .legalFor(allFloatScalarsAndVectors);
316
317 getActionDefinitionsBuilder(G_FCOPYSIGN)
318 .legalForCartesianProduct(allFloatScalarsAndVectors,
319 allFloatScalarsAndVectors);
320
321 getActionDefinitionsBuilder(G_FPOWI).legalForCartesianProduct(
322 allFloatScalarsAndVectors, allIntScalarsAndVectors);
323
Ilia Diachkov698c8002022-08-31 14:53:02 +0300324 if (ST.canUseExtInstSet(SPIRV::InstructionSet::OpenCL_std)) {
Ilia Diachkov698c8002022-08-31 14:53:02 +0300325 getActionDefinitionsBuilder(
326 {G_CTTZ, G_CTTZ_ZERO_UNDEF, G_CTLZ, G_CTLZ_ZERO_UNDEF})
327 .legalForCartesianProduct(allIntScalarsAndVectors,
328 allIntScalarsAndVectors);
329
330 // Struct return types become a single scalar, so cannot easily legalize.
331 getActionDefinitionsBuilder({G_SMULH, G_UMULH}).alwaysLegal();
332 }
333
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300334 getLegacyLegalizerInfo().computeTables();
335 verify(*ST.getInstrInfo());
336}
337
Vyacheslav Levytskyyb5132b72024-11-29 20:44:25 +0100338static Register convertPtrToInt(Register Reg, LLT ConvTy, SPIRVType *SpvType,
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300339 LegalizerHelper &Helper,
340 MachineRegisterInfo &MRI,
341 SPIRVGlobalRegistry *GR) {
342 Register ConvReg = MRI.createGenericVirtualRegister(ConvTy);
Vyacheslav Levytskyyb5132b72024-11-29 20:44:25 +0100343 MRI.setRegClass(ConvReg, GR->getRegClass(SpvType));
344 GR->assignSPIRVTypeToVReg(SpvType, ConvReg, Helper.MIRBuilder.getMF());
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300345 Helper.MIRBuilder.buildInstr(TargetOpcode::G_PTRTOINT)
346 .addDef(ConvReg)
347 .addUse(Reg);
348 return ConvReg;
349}
350
David Greend659bd12024-01-03 07:59:36 +0000351bool SPIRVLegalizerInfo::legalizeCustom(
352 LegalizerHelper &Helper, MachineInstr &MI,
353 LostDebugLocObserver &LocObserver) const {
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300354 auto Opc = MI.getOpcode();
355 MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
Vyacheslav Levytskyy54cc4142025-03-26 17:58:10 +0100356 if (Opc == TargetOpcode::G_ICMP) {
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300357 assert(GR->getSPIRVTypeForVReg(MI.getOperand(0).getReg()));
358 auto &Op0 = MI.getOperand(2);
359 auto &Op1 = MI.getOperand(3);
360 Register Reg0 = Op0.getReg();
361 Register Reg1 = Op1.getReg();
362 CmpInst::Predicate Cond =
363 static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
364 if ((!ST->canDirectlyComparePointers() ||
365 (Cond != CmpInst::ICMP_EQ && Cond != CmpInst::ICMP_NE)) &&
366 MRI.getType(Reg0).isPointer() && MRI.getType(Reg1).isPointer()) {
367 LLT ConvT = LLT::scalar(ST->getPointerSize());
368 Type *LLVMTy = IntegerType::get(MI.getMF()->getFunction().getContext(),
369 ST->getPointerSize());
Vyacheslav Levytskyyd21b2e62025-02-25 14:44:12 +0100370 SPIRVType *SpirvTy = GR->getOrCreateSPIRVType(
371 LLVMTy, Helper.MIRBuilder, SPIRV::AccessQualifier::ReadWrite, true);
Ilia Diachkoveab7d362022-04-14 01:11:15 +0300372 Op0.setReg(convertPtrToInt(Reg0, ConvT, SpirvTy, Helper, MRI, GR));
373 Op1.setReg(convertPtrToInt(Reg1, ConvT, SpirvTy, Helper, MRI, GR));
374 }
375 return true;
376 }
377 // TODO: implement legalization for other opcodes.
378 return true;
379}