LLVM 17.0.0git
X86LegalizerInfo.cpp
Go to the documentation of this file.
1//===- X86LegalizerInfo.cpp --------------------------------------*- 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/// \file
9/// This file implements the targeting of the Machinelegalizer class for X86.
10/// \todo This should be generated by TableGen.
11//===----------------------------------------------------------------------===//
12
13#include "X86LegalizerInfo.h"
14#include "X86Subtarget.h"
15#include "X86TargetMachine.h"
20#include "llvm/IR/Type.h"
21
22using namespace llvm;
23using namespace TargetOpcode;
24using namespace LegalizeActions;
25
26/// FIXME: The following static functions are SizeChangeStrategy functions
27/// that are meant to temporarily mimic the behaviour of the old legalization
28/// based on doubling/halving non-legal types as closely as possible. This is
29/// not entirly possible as only legalizing the types that are exactly a power
30/// of 2 times the size of the legal types would require specifying all those
31/// sizes explicitly.
32/// In practice, not specifying those isn't a problem, and the below functions
33/// should disappear quickly as we add support for legalizing non-power-of-2
34/// sized types further.
38 for (unsigned i = 0; i < v.size(); ++i) {
39 result.push_back(v[i]);
40 if (i + 1 < v[i].first && i + 1 < v.size() &&
41 v[i + 1].first != v[i].first + 1)
42 result.push_back({v[i].first + 1, LegacyLegalizeActions::Unsupported});
43 }
44}
45
48 assert(v.size() >= 1);
49 assert(v[0].first > 1);
54 auto Largest = result.back().first;
55 result.push_back({Largest + 1, LegacyLegalizeActions::Unsupported});
56 return result;
57}
58
60 const X86TargetMachine &TM)
61 : Subtarget(STI), TM(TM) {
62
63 setLegalizerInfo32bit();
64 setLegalizerInfo64bit();
65 setLegalizerInfoSSE1();
66 setLegalizerInfoSSE2();
67 setLegalizerInfoSSE41();
68 setLegalizerInfoSSE42();
69 setLegalizerInfoAVX();
70 setLegalizerInfoAVX2();
71 setLegalizerInfoAVX512();
72 setLegalizerInfoAVX512DQ();
73 setLegalizerInfoAVX512BW();
74
75 const LLT s16 = LLT::scalar(16);
76 const LLT s32 = LLT::scalar(32);
77 const LLT s64 = LLT::scalar(64);
78
79 getActionDefinitionsBuilder(G_INTRINSIC_ROUNDEVEN)
80 .scalarize(0)
81 .minScalar(0, LLT::scalar(32))
82 .libcall();
83
84 auto &LegacyInfo = getLegacyLegalizerInfo();
85 LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(G_PHI, 0, widen_1);
86 for (unsigned BinOp : {G_SUB, G_MUL, G_AND, G_OR, G_XOR})
87 LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(BinOp, 0, widen_1);
88 for (unsigned MemOp : {G_LOAD, G_STORE})
89 LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(
91 LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(
92 G_PTR_ADD, 1,
94 LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(
95 G_CONSTANT, 0,
97
98 getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE, G_MEMSET}).libcall();
99
100
101 if (Subtarget.is64Bit()) {
102 if (Subtarget.hasPOPCNT()) {
103 // popcount
105 .legalFor({{s16, s16}, {s32, s32}, {s64, s64}})
106 .widenScalarToNextPow2(1, /*Min=*/16)
107 .clampScalar(1, s16, s64);
108 }
109
110 if (Subtarget.hasLZCNT()) {
111 // count leading zeros (LZCNT)
113 .legalFor({{s16, s16}, {s32, s32}, {s64, s64}})
114 .widenScalarToNextPow2(1, /*Min=*/16)
115 .clampScalar(1, s16, s64);
116 }
117 } else { // 32-bit
118 if (Subtarget.hasPOPCNT()) {
119 // popcount
121 .legalFor({{s16, s16}, {s32, s32}})
122 .widenScalarToNextPow2(1, /*Min=*/16)
123 .clampScalar(1, s16, s32);
124 }
125
126 if (Subtarget.hasLZCNT()) {
127 // count leading zeros (LZCNT)
129 .legalFor({{s16, s16}, {s32, s32}})
130 .widenScalarToNextPow2(1, /*Min=*/16)
131 .clampScalar(1, s16, s32);
132 }
133 }
134
135 LegacyInfo.computeTables();
136 verify(*STI.getInstrInfo());
137}
138
140 MachineInstr &MI) const {
141 return true;
142}
143
144void X86LegalizerInfo::setLegalizerInfo32bit() {
145
146 const LLT p0 = LLT::pointer(0, TM.getPointerSizeInBits(0));
147 const LLT s1 = LLT::scalar(1);
148 const LLT s8 = LLT::scalar(8);
149 const LLT s16 = LLT::scalar(16);
150 const LLT s32 = LLT::scalar(32);
151 const LLT s64 = LLT::scalar(64);
152 const LLT s128 = LLT::scalar(128);
153
154 auto &LegacyInfo = getLegacyLegalizerInfo();
155
156 for (auto Ty : {p0, s1, s8, s16, s32})
157 LegacyInfo.setAction({G_IMPLICIT_DEF, Ty}, LegacyLegalizeActions::Legal);
158
159 for (auto Ty : {s8, s16, s32, p0})
160 LegacyInfo.setAction({G_PHI, Ty}, LegacyLegalizeActions::Legal);
161
162 for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR})
163 for (auto Ty : {s8, s16, s32})
164 LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal);
165
166 for (unsigned Op : {G_UADDE}) {
167 LegacyInfo.setAction({Op, s32}, LegacyLegalizeActions::Legal);
168 LegacyInfo.setAction({Op, 1, s1}, LegacyLegalizeActions::Legal);
169 }
170
171 for (unsigned MemOp : {G_LOAD, G_STORE}) {
172 for (auto Ty : {s8, s16, s32, p0})
173 LegacyInfo.setAction({MemOp, Ty}, LegacyLegalizeActions::Legal);
174
175 // And everything's fine in addrspace 0.
176 LegacyInfo.setAction({MemOp, 1, p0}, LegacyLegalizeActions::Legal);
177 }
178
179 // Pointer-handling
180 LegacyInfo.setAction({G_FRAME_INDEX, p0}, LegacyLegalizeActions::Legal);
181 LegacyInfo.setAction({G_GLOBAL_VALUE, p0}, LegacyLegalizeActions::Legal);
182
183 LegacyInfo.setAction({G_PTR_ADD, p0}, LegacyLegalizeActions::Legal);
184 LegacyInfo.setAction({G_PTR_ADD, 1, s32}, LegacyLegalizeActions::Legal);
185
186 if (!Subtarget.is64Bit()) {
188 .legalForCartesianProduct({s1, s8, s16, s32}, {p0})
189 .maxScalar(0, s32)
190 .widenScalarToNextPow2(0, /*Min*/ 8);
191 getActionDefinitionsBuilder(G_INTTOPTR).legalFor({{p0, s32}});
192
193 // Shifts and SDIV
195 {G_SDIV, G_SREM, G_UDIV, G_UREM})
196 .legalFor({s8, s16, s32})
197 .clampScalar(0, s8, s32);
198
200 {G_SHL, G_LSHR, G_ASHR})
201 .legalFor({{s8, s8}, {s16, s8}, {s32, s8}})
202 .clampScalar(0, s8, s32)
203 .clampScalar(1, s8, s8);
204
205 // Comparison
207 .legalForCartesianProduct({s8}, {s8, s16, s32, p0})
208 .clampScalar(0, s8, s8);
209 }
210
211 // Control-flow
212 LegacyInfo.setAction({G_BRCOND, s1}, LegacyLegalizeActions::Legal);
213
214 // Constants
215 for (auto Ty : {s8, s16, s32, p0})
216 LegacyInfo.setAction({TargetOpcode::G_CONSTANT, Ty},
218
219 // Extensions
220 for (auto Ty : {s8, s16, s32}) {
221 LegacyInfo.setAction({G_ZEXT, Ty}, LegacyLegalizeActions::Legal);
222 LegacyInfo.setAction({G_SEXT, Ty}, LegacyLegalizeActions::Legal);
223 LegacyInfo.setAction({G_ANYEXT, Ty}, LegacyLegalizeActions::Legal);
224 }
225 LegacyInfo.setAction({G_ANYEXT, s128}, LegacyLegalizeActions::Legal);
226 getActionDefinitionsBuilder(G_SEXT_INREG).lower();
227
228 // Merge/Unmerge
229 for (const auto &Ty : {s16, s32, s64}) {
230 LegacyInfo.setAction({G_MERGE_VALUES, Ty}, LegacyLegalizeActions::Legal);
231 LegacyInfo.setAction({G_UNMERGE_VALUES, 1, Ty},
233 }
234 for (const auto &Ty : {s8, s16, s32}) {
235 LegacyInfo.setAction({G_MERGE_VALUES, 1, Ty}, LegacyLegalizeActions::Legal);
236 LegacyInfo.setAction({G_UNMERGE_VALUES, Ty}, LegacyLegalizeActions::Legal);
237 }
238}
239
240void X86LegalizerInfo::setLegalizerInfo64bit() {
241
242 if (!Subtarget.is64Bit())
243 return;
244
245 const LLT p0 = LLT::pointer(0, TM.getPointerSizeInBits(0));
246 const LLT s1 = LLT::scalar(1);
247 const LLT s8 = LLT::scalar(8);
248 const LLT s16 = LLT::scalar(16);
249 const LLT s32 = LLT::scalar(32);
250 const LLT s64 = LLT::scalar(64);
251 const LLT s128 = LLT::scalar(128);
252
253 auto &LegacyInfo = getLegacyLegalizerInfo();
254
255 LegacyInfo.setAction({G_IMPLICIT_DEF, s64}, LegacyLegalizeActions::Legal);
256 // Need to have that, as tryFoldImplicitDef will create this pattern:
257 // s128 = EXTEND (G_IMPLICIT_DEF s32/s64) -> s128 = G_IMPLICIT_DEF
258 LegacyInfo.setAction({G_IMPLICIT_DEF, s128}, LegacyLegalizeActions::Legal);
259
260 LegacyInfo.setAction({G_PHI, s64}, LegacyLegalizeActions::Legal);
261
262 for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR})
263 LegacyInfo.setAction({BinOp, s64}, LegacyLegalizeActions::Legal);
264
265 for (unsigned MemOp : {G_LOAD, G_STORE})
266 LegacyInfo.setAction({MemOp, s64}, LegacyLegalizeActions::Legal);
267
268 // Pointer-handling
269 LegacyInfo.setAction({G_PTR_ADD, 1, s64}, LegacyLegalizeActions::Legal);
271 .legalForCartesianProduct({s1, s8, s16, s32, s64}, {p0})
272 .maxScalar(0, s64)
273 .widenScalarToNextPow2(0, /*Min*/ 8);
274 getActionDefinitionsBuilder(G_INTTOPTR).legalFor({{p0, s64}});
275
276 // Constants
277 LegacyInfo.setAction({TargetOpcode::G_CONSTANT, s64},
279
280 // Extensions
281 for (unsigned extOp : {G_ZEXT, G_SEXT, G_ANYEXT}) {
282 LegacyInfo.setAction({extOp, s64}, LegacyLegalizeActions::Legal);
283 }
284
286 .legalForCartesianProduct({s32, s64})
287 .clampScalar(1, s32, s64)
289 .clampScalar(0, s32, s64)
291
293 .legalForCartesianProduct({s32, s64})
294 .clampScalar(1, s32, s64)
296 .clampScalar(0, s32, s64)
298
299 // Comparison
301 .legalForCartesianProduct({s8}, {s8, s16, s32, s64, p0})
302 .clampScalar(0, s8, s8);
303
305 .legalForCartesianProduct({s8}, {s32, s64})
306 .clampScalar(0, s8, s8)
307 .clampScalar(1, s32, s64)
309
310 // Divisions
312 {G_SDIV, G_SREM, G_UDIV, G_UREM})
313 .legalFor({s8, s16, s32, s64})
314 .clampScalar(0, s8, s64);
315
316 // Shifts
318 {G_SHL, G_LSHR, G_ASHR})
319 .legalFor({{s8, s8}, {s16, s8}, {s32, s8}, {s64, s8}})
320 .clampScalar(0, s8, s64)
321 .clampScalar(1, s8, s8);
322
323 // Merge/Unmerge
324 LegacyInfo.setAction({G_MERGE_VALUES, s128}, LegacyLegalizeActions::Legal);
325 LegacyInfo.setAction({G_UNMERGE_VALUES, 1, s128},
327 LegacyInfo.setAction({G_MERGE_VALUES, 1, s128}, LegacyLegalizeActions::Legal);
328 LegacyInfo.setAction({G_UNMERGE_VALUES, s128}, LegacyLegalizeActions::Legal);
329
330}
331
332void X86LegalizerInfo::setLegalizerInfoSSE1() {
333 if (!Subtarget.hasSSE1())
334 return;
335
336 const LLT s32 = LLT::scalar(32);
337 const LLT s64 = LLT::scalar(64);
338 const LLT v4s32 = LLT::fixed_vector(4, 32);
339 const LLT v2s64 = LLT::fixed_vector(2, 64);
340
341 auto &LegacyInfo = getLegacyLegalizerInfo();
342
343 for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV})
344 for (auto Ty : {s32, v4s32})
345 LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal);
346
347 for (unsigned MemOp : {G_LOAD, G_STORE})
348 for (auto Ty : {v4s32, v2s64})
349 LegacyInfo.setAction({MemOp, Ty}, LegacyLegalizeActions::Legal);
350
351 // Constants
352 LegacyInfo.setAction({TargetOpcode::G_FCONSTANT, s32},
354
355 // Merge/Unmerge
356 for (const auto &Ty : {v4s32, v2s64}) {
357 LegacyInfo.setAction({G_CONCAT_VECTORS, Ty}, LegacyLegalizeActions::Legal);
358 LegacyInfo.setAction({G_UNMERGE_VALUES, 1, Ty},
360 }
361 LegacyInfo.setAction({G_MERGE_VALUES, 1, s64}, LegacyLegalizeActions::Legal);
362 LegacyInfo.setAction({G_UNMERGE_VALUES, s64}, LegacyLegalizeActions::Legal);
363}
364
365void X86LegalizerInfo::setLegalizerInfoSSE2() {
366 if (!Subtarget.hasSSE2())
367 return;
368
369 const LLT s32 = LLT::scalar(32);
370 const LLT s64 = LLT::scalar(64);
371 const LLT v16s8 = LLT::fixed_vector(16, 8);
372 const LLT v8s16 = LLT::fixed_vector(8, 16);
373 const LLT v4s32 = LLT::fixed_vector(4, 32);
374 const LLT v2s64 = LLT::fixed_vector(2, 64);
375
376 const LLT v32s8 = LLT::fixed_vector(32, 8);
377 const LLT v16s16 = LLT::fixed_vector(16, 16);
378 const LLT v8s32 = LLT::fixed_vector(8, 32);
379 const LLT v4s64 = LLT::fixed_vector(4, 64);
380
381 auto &LegacyInfo = getLegacyLegalizerInfo();
382
383 for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV})
384 for (auto Ty : {s64, v2s64})
385 LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal);
386
387 for (unsigned BinOp : {G_ADD, G_SUB})
388 for (auto Ty : {v16s8, v8s16, v4s32, v2s64})
389 LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal);
390
391 LegacyInfo.setAction({G_MUL, v8s16}, LegacyLegalizeActions::Legal);
392
393 LegacyInfo.setAction({G_FPEXT, s64}, LegacyLegalizeActions::Legal);
394 LegacyInfo.setAction({G_FPEXT, 1, s32}, LegacyLegalizeActions::Legal);
395
396 LegacyInfo.setAction({G_FPTRUNC, s32}, LegacyLegalizeActions::Legal);
397 LegacyInfo.setAction({G_FPTRUNC, 1, s64}, LegacyLegalizeActions::Legal);
398
399 // Constants
400 LegacyInfo.setAction({TargetOpcode::G_FCONSTANT, s64},
402
403 // Merge/Unmerge
404 for (const auto &Ty :
405 {v16s8, v32s8, v8s16, v16s16, v4s32, v8s32, v2s64, v4s64}) {
406 LegacyInfo.setAction({G_CONCAT_VECTORS, Ty}, LegacyLegalizeActions::Legal);
407 LegacyInfo.setAction({G_UNMERGE_VALUES, 1, Ty},
409 }
410 for (const auto &Ty : {v16s8, v8s16, v4s32, v2s64}) {
411 LegacyInfo.setAction({G_CONCAT_VECTORS, 1, Ty},
413 LegacyInfo.setAction({G_UNMERGE_VALUES, Ty}, LegacyLegalizeActions::Legal);
414 }
415}
416
417void X86LegalizerInfo::setLegalizerInfoSSE41() {
418 if (!Subtarget.hasSSE41())
419 return;
420
421 const LLT v4s32 = LLT::fixed_vector(4, 32);
422
423 auto &LegacyInfo = getLegacyLegalizerInfo();
424
425 LegacyInfo.setAction({G_MUL, v4s32}, LegacyLegalizeActions::Legal);
426}
427
428void X86LegalizerInfo::setLegalizerInfoSSE42() {
429 if (!Subtarget.hasSSE42())
430 return;
431
432}
433
434void X86LegalizerInfo::setLegalizerInfoAVX() {
435 if (!Subtarget.hasAVX())
436 return;
437
438 const LLT v16s8 = LLT::fixed_vector(16, 8);
439 const LLT v8s16 = LLT::fixed_vector(8, 16);
440 const LLT v4s32 = LLT::fixed_vector(4, 32);
441 const LLT v2s64 = LLT::fixed_vector(2, 64);
442
443 const LLT v32s8 = LLT::fixed_vector(32, 8);
444 const LLT v64s8 = LLT::fixed_vector(64, 8);
445 const LLT v16s16 = LLT::fixed_vector(16, 16);
446 const LLT v32s16 = LLT::fixed_vector(32, 16);
447 const LLT v8s32 = LLT::fixed_vector(8, 32);
448 const LLT v16s32 = LLT::fixed_vector(16, 32);
449 const LLT v4s64 = LLT::fixed_vector(4, 64);
450 const LLT v8s64 = LLT::fixed_vector(8, 64);
451
452 auto &LegacyInfo = getLegacyLegalizerInfo();
453
454 for (unsigned MemOp : {G_LOAD, G_STORE})
455 for (auto Ty : {v8s32, v4s64})
456 LegacyInfo.setAction({MemOp, Ty}, LegacyLegalizeActions::Legal);
457
458 for (auto Ty : {v32s8, v16s16, v8s32, v4s64}) {
459 LegacyInfo.setAction({G_INSERT, Ty}, LegacyLegalizeActions::Legal);
460 LegacyInfo.setAction({G_EXTRACT, 1, Ty}, LegacyLegalizeActions::Legal);
461 }
462 for (auto Ty : {v16s8, v8s16, v4s32, v2s64}) {
463 LegacyInfo.setAction({G_INSERT, 1, Ty}, LegacyLegalizeActions::Legal);
464 LegacyInfo.setAction({G_EXTRACT, Ty}, LegacyLegalizeActions::Legal);
465 }
466 // Merge/Unmerge
467 for (const auto &Ty :
468 {v32s8, v64s8, v16s16, v32s16, v8s32, v16s32, v4s64, v8s64}) {
469 LegacyInfo.setAction({G_CONCAT_VECTORS, Ty}, LegacyLegalizeActions::Legal);
470 LegacyInfo.setAction({G_UNMERGE_VALUES, 1, Ty},
472 }
473 for (const auto &Ty :
474 {v16s8, v32s8, v8s16, v16s16, v4s32, v8s32, v2s64, v4s64}) {
475 LegacyInfo.setAction({G_CONCAT_VECTORS, 1, Ty},
477 LegacyInfo.setAction({G_UNMERGE_VALUES, Ty}, LegacyLegalizeActions::Legal);
478 }
479}
480
481void X86LegalizerInfo::setLegalizerInfoAVX2() {
482 if (!Subtarget.hasAVX2())
483 return;
484
485 const LLT v32s8 = LLT::fixed_vector(32, 8);
486 const LLT v16s16 = LLT::fixed_vector(16, 16);
487 const LLT v8s32 = LLT::fixed_vector(8, 32);
488 const LLT v4s64 = LLT::fixed_vector(4, 64);
489
490 const LLT v64s8 = LLT::fixed_vector(64, 8);
491 const LLT v32s16 = LLT::fixed_vector(32, 16);
492 const LLT v16s32 = LLT::fixed_vector(16, 32);
493 const LLT v8s64 = LLT::fixed_vector(8, 64);
494
495 auto &LegacyInfo = getLegacyLegalizerInfo();
496
497 for (unsigned BinOp : {G_ADD, G_SUB})
498 for (auto Ty : {v32s8, v16s16, v8s32, v4s64})
499 LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal);
500
501 for (auto Ty : {v16s16, v8s32})
502 LegacyInfo.setAction({G_MUL, Ty}, LegacyLegalizeActions::Legal);
503
504 // Merge/Unmerge
505 for (const auto &Ty : {v64s8, v32s16, v16s32, v8s64}) {
506 LegacyInfo.setAction({G_CONCAT_VECTORS, Ty}, LegacyLegalizeActions::Legal);
507 LegacyInfo.setAction({G_UNMERGE_VALUES, 1, Ty},
509 }
510 for (const auto &Ty : {v32s8, v16s16, v8s32, v4s64}) {
511 LegacyInfo.setAction({G_CONCAT_VECTORS, 1, Ty},
513 LegacyInfo.setAction({G_UNMERGE_VALUES, Ty}, LegacyLegalizeActions::Legal);
514 }
515
516 getActionDefinitionsBuilder({G_AND, G_OR, G_XOR})
517 .legalFor({v8s32, v4s64});
518}
519
520void X86LegalizerInfo::setLegalizerInfoAVX512() {
521 if (!Subtarget.hasAVX512())
522 return;
523
524 const LLT v16s8 = LLT::fixed_vector(16, 8);
525 const LLT v8s16 = LLT::fixed_vector(8, 16);
526 const LLT v4s32 = LLT::fixed_vector(4, 32);
527 const LLT v2s64 = LLT::fixed_vector(2, 64);
528
529 const LLT v32s8 = LLT::fixed_vector(32, 8);
530 const LLT v16s16 = LLT::fixed_vector(16, 16);
531 const LLT v8s32 = LLT::fixed_vector(8, 32);
532 const LLT v4s64 = LLT::fixed_vector(4, 64);
533
534 const LLT v64s8 = LLT::fixed_vector(64, 8);
535 const LLT v32s16 = LLT::fixed_vector(32, 16);
536 const LLT v16s32 = LLT::fixed_vector(16, 32);
537 const LLT v8s64 = LLT::fixed_vector(8, 64);
538
539 auto &LegacyInfo = getLegacyLegalizerInfo();
540
541 for (unsigned BinOp : {G_ADD, G_SUB})
542 for (auto Ty : {v16s32, v8s64})
543 LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal);
544
545 LegacyInfo.setAction({G_MUL, v16s32}, LegacyLegalizeActions::Legal);
546
547 for (unsigned MemOp : {G_LOAD, G_STORE})
548 for (auto Ty : {v16s32, v8s64})
549 LegacyInfo.setAction({MemOp, Ty}, LegacyLegalizeActions::Legal);
550
551 for (auto Ty : {v64s8, v32s16, v16s32, v8s64}) {
552 LegacyInfo.setAction({G_INSERT, Ty}, LegacyLegalizeActions::Legal);
553 LegacyInfo.setAction({G_EXTRACT, 1, Ty}, LegacyLegalizeActions::Legal);
554 }
555 for (auto Ty : {v32s8, v16s16, v8s32, v4s64, v16s8, v8s16, v4s32, v2s64}) {
556 LegacyInfo.setAction({G_INSERT, 1, Ty}, LegacyLegalizeActions::Legal);
557 LegacyInfo.setAction({G_EXTRACT, Ty}, LegacyLegalizeActions::Legal);
558 }
559
560 /************ VLX *******************/
561 if (!Subtarget.hasVLX())
562 return;
563
564 for (auto Ty : {v4s32, v8s32})
565 LegacyInfo.setAction({G_MUL, Ty}, LegacyLegalizeActions::Legal);
566}
567
568void X86LegalizerInfo::setLegalizerInfoAVX512DQ() {
569 if (!(Subtarget.hasAVX512() && Subtarget.hasDQI()))
570 return;
571
572 const LLT v8s64 = LLT::fixed_vector(8, 64);
573
574 auto &LegacyInfo = getLegacyLegalizerInfo();
575
576 LegacyInfo.setAction({G_MUL, v8s64}, LegacyLegalizeActions::Legal);
577
578 /************ VLX *******************/
579 if (!Subtarget.hasVLX())
580 return;
581
582 const LLT v2s64 = LLT::fixed_vector(2, 64);
583 const LLT v4s64 = LLT::fixed_vector(4, 64);
584
585 for (auto Ty : {v2s64, v4s64})
586 LegacyInfo.setAction({G_MUL, Ty}, LegacyLegalizeActions::Legal);
587}
588
589void X86LegalizerInfo::setLegalizerInfoAVX512BW() {
590 if (!(Subtarget.hasAVX512() && Subtarget.hasBWI()))
591 return;
592
593 const LLT v64s8 = LLT::fixed_vector(64, 8);
594 const LLT v32s16 = LLT::fixed_vector(32, 16);
595
596 auto &LegacyInfo = getLegacyLegalizerInfo();
597
598 for (unsigned BinOp : {G_ADD, G_SUB})
599 for (auto Ty : {v64s8, v32s16})
600 LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal);
601
602 LegacyInfo.setAction({G_MUL, v32s16}, LegacyLegalizeActions::Legal);
603
604 /************ VLX *******************/
605 if (!Subtarget.hasVLX())
606 return;
607
608 const LLT v8s16 = LLT::fixed_vector(8, 16);
609 const LLT v16s16 = LLT::fixed_vector(16, 16);
610
611 for (auto Ty : {v8s16, v16s16})
612 LegacyInfo.setAction({G_MUL, Ty}, LegacyLegalizeActions::Legal);
613}
IRTranslator LLVM IR MI
ppc ctr loops verify
const char LLVMTargetMachineRef TM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static LegacyLegalizerInfo::SizeAndActionsVec widen_1(const LegacyLegalizerInfo::SizeAndActionsVec &v)
static void addAndInterleaveWithUnsupported(LegacyLegalizerInfo::SizeAndActionsVec &result, const LegacyLegalizerInfo::SizeAndActionsVec &v)
FIXME: The following static functions are SizeChangeStrategy functions that are meant to temporarily ...
This file declares the targeting of the Machinelegalizer class for X86.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:42
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
Definition: LowLevelType.h:49
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
Definition: LowLevelType.h:76
static SizeAndActionsVec narrowToSmallerAndWidenToSmallest(const SizeAndActionsVec &v)
static SizeAndActionsVec widenToLargerTypesUnsupportedOtherwise(const SizeAndActionsVec &v)
std::vector< SizeAndAction > SizeAndActionsVec
static SizeAndActionsVec widenToLargerTypesAndNarrowToLargest(const SizeAndActionsVec &v)
A SizeChangeStrategy for the common case where legalization for a particular operation consists of wi...
LegalizeRuleSet & minScalar(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at least as wide as Ty.
LegalizeRuleSet & legalFor(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list.
LegalizeRuleSet & libcall()
The instruction is emitted as a library call.
LegalizeRuleSet & lower()
The instruction is lowered.
LegalizeRuleSet & clampScalar(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
LegalizeRuleSet & widenScalarToNextPow2(unsigned TypeIdx, unsigned MinSize=0)
Widen the scalar to the next power of two that is at least MinSize.
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 & getActionDefinitionsBuilder(unsigned Opcode)
Get the action definition builder for the given opcode.
const LegacyLegalizerInfo & getLegacyLegalizerInfo() const
Representation of each machine instruction.
Definition: MachineInstr.h:68
unsigned getPointerSizeInBits(unsigned AS) const
bool legalizeIntrinsic(LegalizerHelper &Helper, MachineInstr &MI) const override
X86LegalizerInfo(const X86Subtarget &STI, const X86TargetMachine &TM)
bool hasSSE1() const
Definition: X86Subtarget.h:199
bool hasSSE42() const
Definition: X86Subtarget.h:204
const X86InstrInfo * getInstrInfo() const override
Definition: X86Subtarget.h:128
bool hasAVX512() const
Definition: X86Subtarget.h:207
bool hasSSE41() const
Definition: X86Subtarget.h:203
bool hasSSE2() const
Definition: X86Subtarget.h:200
bool hasAVX() const
Definition: X86Subtarget.h:205
bool hasAVX2() const
Definition: X86Subtarget.h:206
@ Legal
The operation is expected to be selectable directly by the target, and no transformation is necessary...
@ Unsupported
This operation is completely unsupported on the target.
@ WidenScalar
The operation should be implemented in terms of a wider scalar base-type.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18