38 bool Is64Bit = Subtarget.is64Bit();
39 bool HasCMOV = Subtarget.canUseCMOV();
40 bool HasSSE1 = Subtarget.hasSSE1();
41 bool HasSSE2 = Subtarget.hasSSE2();
42 bool HasSSE41 = Subtarget.hasSSE41();
43 bool HasAVX = Subtarget.hasAVX();
44 bool HasAVX2 = Subtarget.hasAVX2();
45 bool HasAVX512 = Subtarget.hasAVX512();
46 bool HasVLX = Subtarget.hasVLX();
47 bool HasDQI = Subtarget.hasAVX512() && Subtarget.hasDQI();
48 bool HasBWI = Subtarget.hasAVX512() && Subtarget.hasBWI();
49 bool UseX87 = !Subtarget.useSoftFloat() && Subtarget.hasX87();
50 bool HasPOPCNT = Subtarget.hasPOPCNT();
51 bool HasLZCNT = Subtarget.hasLZCNT();
52 bool HasBMI = Subtarget.hasBMI();
62 const LLT sMaxScalar = Subtarget.is64Bit() ? s64 : s32;
83 const LLT s8MaxVector = HasAVX512 ? v64s8 : HasAVX ? v32s8 : v16s8;
84 const LLT s16MaxVector = HasAVX512 ? v32s16 : HasAVX ? v16s16 : v8s16;
85 const LLT s32MaxVector = HasAVX512 ? v16s32 : HasAVX ? v8s32 : v4s32;
86 const LLT s64MaxVector = HasAVX512 ? v8s64 : HasAVX ? v4s64 : v2s64;
95 {G_IMPLICIT_DEF, G_PHI, G_FREEZE, G_CONSTANT_FOLD_BARRIER})
96 .legalFor({p0, s1, s8, s16, s32, s64})
97 .legalFor(UseX87, {s80})
98 .legalFor(Is64Bit, {s128})
99 .legalFor(HasSSE2, {v16s8, v8s16, v4s32, v2s64})
100 .legalFor(HasAVX, {v32s8, v16s16, v8s32, v4s64})
101 .legalFor(HasAVX512, {v64s8, v32s16, v16s32, v8s64})
102 .widenScalarOrEltToNextPow2(0, 8)
103 .clampScalarOrElt(0, s8, sMaxScalar)
104 .moreElementsToNextPow2(0)
105 .clampNumElements(0, v16s8, s8MaxVector)
106 .clampNumElements(0, v8s16, s16MaxVector)
107 .clampNumElements(0, v4s32, s32MaxVector)
108 .clampNumElements(0, v2s64, s64MaxVector)
109 .clampMaxNumElements(0, p0,
110 Is64Bit ? s64MaxVector.getNumElements()
111 : s32MaxVector.getNumElements())
116 .legalFor(Is64Bit, {s64})
117 .widenScalarToNextPow2(0, 8)
121 .widenScalarIf(
typeIs(1, s16),
123 return std::pair<unsigned, LLT>(1, s32);
128 {G_FCOS, G_FCOSH, G_FACOS, G_FSIN, G_FSINH, G_FASIN, G_FTAN,
129 G_FTANH, G_FATAN, G_FATAN2, G_FPOW, G_FEXP, G_FEXP2, G_FEXP10,
130 G_FLOG, G_FLOG2, G_FLOG10, G_FPOWI, G_FSINCOS, G_FCEIL, G_FFLOOR})
134 .
legalFor(UseX87 && !HasSSE1, {s32})
135 .legalFor(UseX87 && !HasSSE2, {s64})
136 .legalFor(UseX87, {s80})
141 .legalFor(HasSSE2 || UseX87, {s64})
142 .legalFor(UseX87, {s80});
148 for (
unsigned Op : {G_MERGE_VALUES, G_UNMERGE_VALUES}) {
149 unsigned BigTyIdx =
Op == G_MERGE_VALUES ? 0 : 1;
150 unsigned LitTyIdx =
Op == G_MERGE_VALUES ? 1 : 0;
157 switch (Q.
Types[BigTyIdx].getSizeInBits()) {
168 switch (Q.
Types[LitTyIdx].getSizeInBits()) {
183 .widenScalarToNextPow2(0, 32)
188 .legalFor({s8, s16, s32})
189 .legalFor(Is64Bit, {s64})
190 .legalFor(HasSSE2, {v16s8, v8s16, v4s32, v2s64})
191 .legalFor(HasAVX2, {v32s8, v16s16, v8s32, v4s64})
192 .legalFor(HasAVX512, {v16s32, v8s64})
193 .legalFor(HasBWI, {v64s8, v32s16})
194 .clampMinNumElements(0, s8, 16)
207 .legalFor({{s8, s8}, {s16, s8}, {s32, s8}})
208 .legalFor(Is64Bit, {{s64, s8}})
209 .widenScalarToNextPow2(0, 32)
217 .legalFor(Is64Bit, {s64})
218 .legalFor(HasSSE2, {v8s16})
219 .legalFor(HasSSE41, {v4s32})
220 .legalFor(HasAVX2, {v16s16, v8s32})
221 .legalFor(HasAVX512, {v16s32})
222 .legalFor(HasDQI, {v8s64})
223 .legalFor(HasDQI && HasVLX, {v2s64, v4s64})
224 .legalFor(HasBWI, {v32s16})
225 .clampMinNumElements(0, s16, 8)
236 .legalFor({s8, s16, s32})
237 .legalFor(Is64Bit, {s64})
238 .widenScalarToNextPow2(0, 32)
244 .legalFor({s8, s16, s32})
245 .legalFor(Is64Bit, {s64})
247 .clampScalar(0, s8, sMaxScalar);
251 .legalFor({{s8, s8}, {s16, s8}, {s32, s8}})
252 .legalFor(Is64Bit, {{s64, s8}})
253 .clampScalar(0, s8, sMaxScalar)
258 .legalFor({s8, s16, s32})
259 .legalFor(Is64Bit, {s64})
260 .legalFor(HasSSE2, {v16s8, v8s16, v4s32, v2s64})
261 .legalFor(HasAVX, {v32s8, v16s16, v8s32, v4s64})
262 .legalFor(HasAVX512, {v64s8, v32s16, v16s32, v8s64})
263 .clampNumElements(0, v16s8, s8MaxVector)
272 const std::initializer_list<LLT> IntTypes32 = {s8, s16, s32, p0};
273 const std::initializer_list<LLT> IntTypes64 = {s8, s16, s32, s64, p0};
277 .clampScalar(0, s8, s8)
284 .legalFor(Is64Bit, {s64})
285 .widenScalarToNextPow2(0, 32)
290 .
legalFor(HasPOPCNT, {{s16, s16}, {s32, s32}})
291 .legalFor(HasPOPCNT && Is64Bit, {{s64, s64}})
292 .widenScalarToNextPow2(1, 16)
298 .
legalFor(HasLZCNT, {{s16, s16}, {s32, s32}})
299 .legalFor(HasLZCNT && Is64Bit, {{s64, s64}})
300 .widenScalarToNextPow2(1, 16)
307 .legalFor(Is64Bit, {{s64, s64}})
308 .widenScalarToNextPow2(1, 16)
313 .
legalFor(HasBMI, {{s16, s16}, {s32, s32}})
314 .legalFor(HasBMI && Is64Bit, {{s64, s64}})
315 .widenScalarToNextPow2(1, 16)
323 const std::initializer_list<LLT> PtrTypes32 = {s1, s8, s16, s32};
324 const std::initializer_list<LLT> PtrTypes64 = {s1, s8, s16, s32, s64};
328 .maxScalar(0, sMaxScalar)
337 .legalFor(Is64Bit, {{p0, s64}})
338 .widenScalarToNextPow2(1, 32)
346 for (
unsigned Op : {G_LOAD, G_STORE}) {
348 Action.legalForTypesWithMemDesc({{s8, p0, s8, 1},
353 {v4s8, p0, v4s8, 1}});
355 Action.legalForTypesWithMemDesc(
356 {{s64, p0, s64, 1}, {v2s32, p0, v2s32, 1}});
359 Action.legalForTypesWithMemDesc({{v4s32, p0, v4s32, 1}});
361 Action.legalForTypesWithMemDesc({{v16s8, p0, v16s8, 1},
362 {v8s16, p0, v8s16, 1},
363 {v2s64, p0, v2s64, 1},
364 {v2p0, p0, v2p0, 1}});
366 Action.legalForTypesWithMemDesc({{v32s8, p0, v32s8, 1},
367 {v16s16, p0, v16s16, 1},
368 {v8s32, p0, v8s32, 1},
369 {v4s64, p0, v4s64, 1},
370 {v4p0, p0, v4p0, 1}});
372 Action.legalForTypesWithMemDesc({{v64s8, p0, v64s8, 1},
373 {v32s16, p0, v32s16, 1},
374 {v16s32, p0, v16s32, 1},
375 {v8s64, p0, v8s64, 1}});
379 Action.legalForTypesWithMemDesc({{s8, p0, s1, 1},
384 Action.legalForTypesWithMemDesc(
385 {{s64, p0, s8, 1}, {s64, p0, s16, 1}, {s64, p0, s32, 1}});
391 Action.widenScalarToNextPow2(0, 8)
392 .clampScalar(0, s8, sMaxScalar)
396 for (
unsigned Op : {G_SEXTLOAD, G_ZEXTLOAD}) {
398 Action.legalForTypesWithMemDesc(
399 {{s16, p0, s8, 1}, {s32, p0, s8, 1}, {s32, p0, s16, 1}});
401 Action.legalForTypesWithMemDesc(
402 {{s64, p0, s8, 1}, {s64, p0, s16, 1}, {s64, p0, s32, 1}});
406 for (
unsigned Op : {G_FPEXTLOAD, G_FPTRUNCSTORE}) {
408 Action.legalForTypesWithMemDesc(
409 UseX87, {{s80, p0, s32, 1}, {s80, p0, s64, 1}, {s64, p0, s32, 1}});
415 .legalFor(Is64Bit, {s64})
416 .widenScalarToNextPow2(0, 8)
423 .legalFor({s8, s16, s32})
424 .legalFor(Is64Bit, {s64})
425 .widenScalarToNextPow2(0, 8)
432 {s1, s8, s16, s32, s64}, {s8, s16, s32, s64, s128});
439 .legalFor(UseX87, {s80});
443 .legalFor({s32, s64})
444 .legalFor(HasSSE1, {v4s32})
445 .legalFor(HasSSE2, {v2s64})
446 .legalFor(HasAVX, {v8s32, v4s64})
447 .legalFor(HasAVX512, {v16s32, v8s64})
448 .legalFor(UseX87, {s80});
452 .legalFor(UseX87 && !Is64Bit, {s64})
457 .
legalFor(HasSSE1 || UseX87, {s8, s32})
458 .legalFor(HasSSE2 || UseX87, {s8, s64})
459 .legalFor(UseX87, {s8, s80})
460 .clampScalar(0, s8, s8)
467 .legalFor(HasAVX, {{v4s64, v4s32}})
468 .legalFor(HasAVX512, {{v8s64, v8s32}})
469 .lowerFor(UseX87, {{s64, s32}, {s80, s32}, {s80, s64}})
474 .legalFor(HasAVX, {{v4s32, v4s64}})
475 .legalFor(HasAVX512, {{v8s32, v8s64}})
476 .lowerFor(UseX87, {{s32, s64}, {s32, s80}, {s64, s80}});
480 .legalFor(HasSSE1 && Is64Bit, {{s32, s64}})
481 .legalFor(HasSSE2, {{s64, s32}})
482 .legalFor(HasSSE2 && Is64Bit, {{s64, s64}})
483 .clampScalar(1, (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar)
486 .clampScalar(0, s32, HasSSE2 ? s64 : s32)
491 .legalFor(HasSSE1 && Is64Bit, {{s64, s32}})
492 .legalFor(HasSSE2, {{s32, s64}})
493 .legalFor(HasSSE2 && Is64Bit, {{s64, s64}})
494 .clampScalar(0, (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar)
497 .clampScalar(1, s32, HasSSE2 ? s64 : s32)
508 .
legalFor(HasAVX512, {{s32, s32}, {s32, s64}, {s64, s32}, {s64, s64}})
511 ((HasSSE1 &&
typeIs(0, s32)(Query)) ||
512 (HasSSE2 &&
typeIs(0, s64)(Query))) &&
518 ((HasSSE1 &&
typeIs(0, s32)(Query)) ||
519 (HasSSE2 &&
typeIs(0, s64)(Query))) &&
520 (Is64Bit &&
typeIs(1, s64)(Query));
522 .clampScalar(0, s32, HasSSE2 ? s64 : s32)
528 .
legalFor(HasAVX512, {{s32, s32}, {s32, s64}, {s64, s32}, {s64, s64}})
531 ((HasSSE1 &&
typeIs(1, s32)(Query)) ||
532 (HasSSE2 &&
typeIs(1, s64)(Query))) &&
541 ((HasSSE1 &&
typeIs(1, s32)(Query)) ||
542 (HasSSE2 &&
typeIs(1, s64)(Query))) &&
543 (Is64Bit &&
typeIs(0, s64)(Query));
545 .clampScalar(0, s32, sMaxScalar)
553 return (HasSSE1 &&
typeInSet(0, {v4s32})(Query)) ||
554 (HasSSE2 &&
typeInSet(0, {v2s64, v8s16, v16s8})(Query)) ||
555 (HasAVX &&
typeInSet(0, {v4s64, v8s32, v16s16, v32s8})(Query)) ||
557 typeInSet(0, {v8s64, v16s32, v32s16, v64s8})(Query));
559 .clampNumElements(0, v16s8, s8MaxVector)
567 unsigned SubIdx = Query.
Opcode == G_EXTRACT ? 0 : 1;
568 unsigned FullIdx = Query.
Opcode == G_EXTRACT ? 1 : 0;
573 {v2s64, v4s64}})(Query)) ||
582 {v4s64, v8s64}})(Query));
589 {{v32s8, v16s8}, {v16s16, v8s16}, {v8s32, v4s32}, {v4s64, v2s64}})
590 .legalFor(HasAVX, {{v64s8, v16s8},
601 .
legalFor({{s16, s32}, {s32, s32}, {p0, s32}})
602 .legalFor(!HasCMOV, {{s8, s32}})
603 .legalFor(Is64Bit, {{s64, s32}})
604 .legalFor(UseX87, {{s80, s32}})
605 .clampScalar(1, s32, s32)
618 .
lowerFor(Is64Bit, {{s1, s32}, {s1, s64}, {s1, s80}});