LLVM 24.0.0git
LegalizerInfo.h
Go to the documentation of this file.
1//===- llvm/CodeGen/GlobalISel/LegalizerInfo.h ------------------*- 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/// Interface for Targets to specify which operations they can successfully
10/// select and how the others should be expanded most efficiently.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
15#define LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
16
22#include "llvm/MC/MCInstrDesc.h"
26#include <cassert>
27#include <cstdint>
28#include <tuple>
29#include <utility>
30
31namespace llvm {
32
34
35class MachineFunction;
36class raw_ostream;
37class LegalizerHelper;
39class MachineInstr;
41class MCInstrInfo;
42
43namespace LegalizeActions {
44enum LegalizeAction : std::uint8_t {
45 /// The operation is expected to be selectable directly by the target, and
46 /// no transformation is necessary.
48
49 /// The operation should be synthesized from multiple instructions acting on
50 /// a narrower scalar base-type. For example a 64-bit add might be
51 /// implemented in terms of 32-bit add-with-carry.
53
54 /// The operation should be implemented in terms of a wider scalar
55 /// base-type. For example a <2 x s8> add could be implemented as a <2
56 /// x s32> add (ignoring the high bits).
58
59 /// The (vector) operation should be implemented by splitting it into
60 /// sub-vectors where the operation is legal. For example a <8 x s64> add
61 /// might be implemented as 4 separate <2 x s64> adds. There can be a leftover
62 /// if there are not enough elements for last sub-vector e.g. <7 x s64> add
63 /// will be implemented as 3 separate <2 x s64> adds and one s64 add. Leftover
64 /// types can be avoided by doing MoreElements first.
66
67 /// The (vector) operation should be implemented by widening the input
68 /// vector and ignoring the lanes added by doing so. For example <2 x i8> is
69 /// rarely legal, but you might perform an <8 x i8> and then only look at
70 /// the first two results.
72
73 /// Perform the operation on a different, but equivalently sized type.
75
76 /// The operation itself must be expressed in terms of simpler actions on
77 /// this target. E.g. a SREM replaced by an SDIV and subtraction.
79
80 /// The operation should be implemented as a call to some kind of runtime
81 /// support library. For example this usually happens on machines that don't
82 /// support floating-point operations natively.
84
85 /// The target wants to do something special with this combination of
86 /// operand and type. A callback will be issued when it is needed.
88
89 /// This operation is completely unsupported on the target. A programming
90 /// error has occurred.
92
93 /// Sentinel value for when no action was found in the specified table.
95};
96} // end namespace LegalizeActions
97LLVM_ABI raw_ostream &operator<<(raw_ostream &OS,
99
101
102/// The LegalityQuery object bundles together all the information that's needed
103/// to decide whether a given operation is legal or not.
104/// For efficiency, it doesn't make a copy of Types so care must be taken not
105/// to free it before using the query.
107 unsigned Opcode;
109
110 struct MemDesc {
113 AtomicOrdering Ordering; //< For cmpxchg this is the success ordering.
114 AtomicOrdering FailureOrdering; //< For cmpxchg, otherwise NotAtomic.
115
116 MemDesc() = default;
122 : MemDesc(MMO.getMemoryType(), MMO.getAlign().value() * 8,
123 MMO.getSuccessOrdering(), MMO.getFailureOrdering()) {}
124 };
125
126 /// Operations which require memory can use this to place requirements on the
127 /// memory type for each MMO.
129
131
135 : Opcode(Opcode), Types(Types), MMODescrs(MMODescrs),
137
138 LLVM_ABI raw_ostream &print(raw_ostream &OS) const;
139};
140
141/// The result of a query. It either indicates a final answer of Legal or
142/// Unsupported or describes an action that must be taken to make an operation
143/// more legal.
145 /// The action to take or the final answer.
147 /// If describing an action, the type index to change. Otherwise zero.
148 unsigned TypeIdx;
149 /// If describing an action, the new type for TypeIdx. Otherwise LLT{}.
151
155
156 bool operator==(const LegalizeActionStep &RHS) const {
157 return std::tie(Action, TypeIdx, NewType) ==
158 std::tie(RHS.Action, RHS.TypeIdx, RHS.NewType);
159 }
160};
161
162using LegalityPredicate = std::function<bool (const LegalityQuery &)>;
164 std::function<std::pair<unsigned, LLT>(const LegalityQuery &)>;
165
172
174 return Type0 == Other.Type0 && Type1 == Other.Type1 &&
175 Align == Other.Align && MemTy == Other.MemTy;
176 }
177
178 /// \returns true if this memory access is legal with for the access described
179 /// by \p Other (The alignment is sufficient for the size and result type).
181 return Type0 == Other.Type0 && Type1 == Other.Type1 &&
182 Align >= Other.Align &&
183 // FIXME: This perhaps should be stricter, but the current legality
184 // rules are written only considering the size.
185 MemTy.getSizeInBits() == Other.MemTy.getSizeInBits();
186 }
187};
188
189/// True iff P is false.
190template <typename Predicate> Predicate predNot(Predicate P) {
191 return [=](const LegalityQuery &Query) { return !P(Query); };
192}
193
194/// True iff P0 and P1 are true.
195template<typename Predicate>
197 return [=](const LegalityQuery &Query) {
198 return P0(Query) && P1(Query);
199 };
200}
201/// True iff all given predicates are true.
202template<typename Predicate, typename... Args>
204 return all(all(P0, P1), args...);
205}
206
207/// True iff P0 or P1 are true.
208template<typename Predicate>
210 return [=](const LegalityQuery &Query) {
211 return P0(Query) || P1(Query);
212 };
213}
214/// True iff any given predicates are true.
215template<typename Predicate, typename... Args>
217 return any(any(P0, P1), args...);
218}
219
220/// True iff the given type index is the specified type.
221LLVM_ABI LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit);
222/// True iff the given type index is one of the specified types.
223LLVM_ABI LegalityPredicate typeInSet(unsigned TypeIdx,
224 std::initializer_list<LLT> TypesInit);
225
226/// True iff the given type index is not the specified type.
227inline LegalityPredicate typeIsNot(unsigned TypeIdx, LLT Type) {
228 return [=](const LegalityQuery &Query) {
229 return Query.Types[TypeIdx] != Type;
230 };
231}
232
233/// True iff the given types for the given pair of type indexes is one of the
234/// specified type pairs.
236typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1,
237 std::initializer_list<std::pair<LLT, LLT>> TypesInit);
238/// True iff the given types for the given tuple of type indexes is one of the
239/// specified type tuple.
241typeTupleInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned Type2,
242 std::initializer_list<std::tuple<LLT, LLT, LLT>> TypesInit);
243/// True iff the given types for the given pair of type indexes is one of the
244/// specified type pairs.
246 unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx,
247 std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit);
248/// True iff the specified type index is a scalar.
249LLVM_ABI LegalityPredicate isScalar(unsigned TypeIdx);
250/// True iff the specified type index is a vector.
251LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx);
252/// True iff the specified type index is a pointer (with any address space).
253LLVM_ABI LegalityPredicate isPointer(unsigned TypeIdx);
254/// True iff the specified type index is a pointer with the specified address
255/// space.
256LLVM_ABI LegalityPredicate isPointer(unsigned TypeIdx, unsigned AddrSpace);
257/// True iff the specified type index is a vector of pointers (with any address
258/// space).
260
261/// True if the type index is a vector with element type \p EltTy
262LLVM_ABI LegalityPredicate elementTypeIs(unsigned TypeIdx, LLT EltTy);
263
264/// True iff the specified type index is a scalar that's narrower than the given
265/// size.
266LLVM_ABI LegalityPredicate scalarNarrowerThan(unsigned TypeIdx, unsigned Size);
267
268/// True iff the specified type index is a scalar that's wider than the given
269/// size.
270LLVM_ABI LegalityPredicate scalarWiderThan(unsigned TypeIdx, unsigned Size);
271
272/// True iff the specified type index is a scalar or vector with an element type
273/// that's narrower than the given size.
275 unsigned Size);
276
277/// True iff the specified type index is a vector with a number of elements
278/// that's greater than the given size.
280 unsigned Size);
281
282/// True iff the specified type index is a vector with a number of elements
283/// that's less than or equal to the given size.
285vectorElementCountIsLessThanOrEqualTo(unsigned TypeIdx, unsigned Size);
286
287/// True iff the specified type index is a scalar or a vector with an element
288/// type that's wider than the given size.
290 unsigned Size);
291
292/// True iff the specified type index is a scalar whose size is not a multiple
293/// of Size.
294LLVM_ABI LegalityPredicate sizeNotMultipleOf(unsigned TypeIdx, unsigned Size);
295
296/// True iff the specified type index is a scalar whose size is not a power of
297/// 2.
298LLVM_ABI LegalityPredicate sizeNotPow2(unsigned TypeIdx);
299
300/// True iff the specified type index is a scalar or vector whose element size
301/// is not a power of 2.
303
304/// True if the total bitwidth of the specified type index is \p Size bits.
305LLVM_ABI LegalityPredicate sizeIs(unsigned TypeIdx, unsigned Size);
306
307/// True iff the specified type indices are both the same bit size.
308LLVM_ABI LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1);
309
310/// True iff the first type index has a larger total bit size than second type
311/// index.
312LLVM_ABI LegalityPredicate largerThan(unsigned TypeIdx0, unsigned TypeIdx1);
313
314/// True iff the first type index has a smaller total bit size than second type
315/// index.
316LLVM_ABI LegalityPredicate smallerThan(unsigned TypeIdx0, unsigned TypeIdx1);
317
318/// True iff the specified MMO index has a size (rounded to bytes) that is not a
319/// power of 2.
321
322/// True iff the specified MMO index has a size that is not an even byte size,
323/// or that even byte size is not a power of 2.
325
326/// True iff the specified type index is a vector whose element count is not a
327/// power of 2.
329/// True iff the specified MMO index has at an atomic ordering of at Ordering or
330/// stronger.
332atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx, AtomicOrdering Ordering);
333
334/// True iff the immediate at the given index has the specified value.
335LLVM_ABI LegalityPredicate immIs(unsigned ImmIdx, int64_t Imm);
336/// True iff the immediate at the given index has one of the specified values.
337LLVM_ABI LegalityPredicate immInSet(unsigned ImmIdx,
338 std::initializer_list<int64_t> ImmsInit);
339/// True iff the immediate at the given index does not have the specified value.
340LLVM_ABI LegalityPredicate immIsNot(unsigned ImmIdx, int64_t Imm);
341} // end namespace LegalityPredicates
342
344/// Select this specific type for the given type index.
345LLVM_ABI LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
346
347/// Keep the same type as the given type index.
348LLVM_ABI LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx);
349
350/// Keep the same scalar or element type as the given type index.
352 unsigned FromTypeIdx);
353
354/// Keep the same scalar or element type as the given type.
355LLVM_ABI LegalizeMutation changeElementTo(unsigned TypeIdx, LLT Ty);
356
357/// Keep the same scalar or element type as \p TypeIdx, but take the number of
358/// elements from \p FromTypeIdx.
360 unsigned FromTypeIdx);
361
362/// Keep the same scalar or element type as \p TypeIdx, but take the number of
363/// elements from \p Ty.
365 ElementCount EC);
366
367/// Change the scalar size or element size to have the same scalar size as type
368/// index \p FromIndex. Unlike changeElementTo, this discards pointer types and
369/// only changes the size.
371 unsigned FromTypeIdx);
372
373/// Change the scalar size or element size to have the same scalar size as the
374/// type \p NewTy. Unlike changeElementTo, this discards pointer types and only
375/// changes the size.
376LLVM_ABI LegalizeMutation changeElementSizeTo(unsigned TypeIdx, LLT NewTy);
377
378/// Widen the scalar type or vector element type for the given type index to the
379/// next power of 2.
381 unsigned Min = 0);
382
383/// Widen the scalar type or vector element type for the given type index to
384/// next multiple of \p Size.
386 unsigned Size);
387
388/// Add more elements to the type for the given type index to the next power of
389/// 2.
391 unsigned Min = 0);
392/// Break up the vector type for the given type index into the element type.
393LLVM_ABI LegalizeMutation scalarize(unsigned TypeIdx);
394} // end namespace LegalizeMutations
395
396/// A single rule in a legalizer info ruleset.
397/// The specified action is chosen when the predicate is true. Where appropriate
398/// for the action (e.g. for WidenScalar) the new type is selected using the
399/// given mutator.
401 LegalityPredicate Predicate;
402 LegalizeAction Action;
403 LegalizeMutation Mutation;
404
405public:
407 LegalizeMutation Mutation = nullptr)
408 : Predicate(Predicate), Action(Action), Mutation(Mutation) {}
409
410 /// Test whether the LegalityQuery matches.
411 bool match(const LegalityQuery &Query) const {
412 return Predicate(Query);
413 }
414
415 LegalizeAction getAction() const { return Action; }
416
417 /// Determine the change to make.
418 std::pair<unsigned, LLT> determineMutation(const LegalityQuery &Query) const {
419 if (Mutation)
420 return Mutation(Query);
421 return std::make_pair(0, LLT{});
422 }
423};
424
426 /// When non-zero, the opcode we are an alias of
427 unsigned AliasOf = 0;
428 /// If true, there is another opcode that aliases this one
429 bool IsAliasedByAnother = false;
431
432#ifndef NDEBUG
433 /// If bit I is set, this rule set contains a rule that may handle (predicate
434 /// or perform an action upon (or both)) the type index I. The uncertainty
435 /// comes from free-form rules executing user-provided lambda functions. We
436 /// conservatively assume such rules do the right thing and cover all type
437 /// indices. The bitset is intentionally 1 bit wider than it absolutely needs
438 /// to be to distinguish such cases from the cases where all type indices are
439 /// individually handled.
444#endif
445
446 unsigned typeIdx(unsigned TypeIdx) {
447 assert(TypeIdx <=
449 "Type Index is out of bounds");
450#ifndef NDEBUG
451 TypeIdxsCovered.set(TypeIdx);
452#endif
453 return TypeIdx;
454 }
455
456 void markAllIdxsAsCovered() {
457#ifndef NDEBUG
458 TypeIdxsCovered.set();
459 ImmIdxsCovered.set();
460#endif
461 }
462
463 void add(const LegalizeRule &Rule) {
464 assert(AliasOf == 0 &&
465 "RuleSet is aliased, change the representative opcode instead");
466 Rules.push_back(Rule);
467 }
468
469 static bool always(const LegalityQuery &) { return true; }
470
471 /// Use the given action when the predicate is true.
472 /// Action should not be an action that requires mutation.
473 LegalizeRuleSet &actionIf(LegalizeAction Action,
475 add({Predicate, Action});
476 return *this;
477 }
478 /// Use the given action when the predicate is true.
479 /// Action should be an action that requires mutation.
482 add({Predicate, Action, Mutation});
483 return *this;
484 }
485 /// Use the given action when type index 0 is any type in the given list.
486 /// Action should not be an action that requires mutation.
487 LegalizeRuleSet &actionFor(LegalizeAction Action,
488 std::initializer_list<LLT> Types) {
489 using namespace LegalityPredicates;
490 return actionIf(Action, typeInSet(typeIdx(0), Types));
491 }
492 /// Use the given action when type index 0 is any type in the given list.
493 /// Action should be an action that requires mutation.
494 LegalizeRuleSet &actionFor(LegalizeAction Action,
495 std::initializer_list<LLT> Types,
497 using namespace LegalityPredicates;
498 return actionIf(Action, typeInSet(typeIdx(0), Types), Mutation);
499 }
500 /// Use the given action when type indexes 0 and 1 is any type pair in the
501 /// given list.
502 /// Action should not be an action that requires mutation.
503 LegalizeRuleSet &actionFor(LegalizeAction Action,
504 std::initializer_list<std::pair<LLT, LLT>> Types) {
505 using namespace LegalityPredicates;
506 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
507 }
508
510 actionFor(LegalizeAction Action,
511 std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
512 using namespace LegalityPredicates;
513 return actionIf(Action,
514 typeTupleInSet(typeIdx(0), typeIdx(1), typeIdx(2), Types));
515 }
516
517 /// Use the given action when type indexes 0 and 1 is any type pair in the
518 /// given list.
519 /// Action should be an action that requires mutation.
520 LegalizeRuleSet &actionFor(LegalizeAction Action,
521 std::initializer_list<std::pair<LLT, LLT>> Types,
523 using namespace LegalityPredicates;
524 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types),
525 Mutation);
526 }
527 /// Use the given action when type index 0 is any type in the given list and
528 /// imm index 0 is anything. Action should not be an action that requires
529 /// mutation.
530 LegalizeRuleSet &actionForTypeWithAnyImm(LegalizeAction Action,
531 std::initializer_list<LLT> Types) {
532 using namespace LegalityPredicates;
533 immIdx(0); // Inform verifier imm idx 0 is handled.
534 return actionIf(Action, typeInSet(typeIdx(0), Types));
535 }
536
537 LegalizeRuleSet &actionForTypeWithAnyImm(
538 LegalizeAction Action, std::initializer_list<std::pair<LLT, LLT>> Types) {
539 using namespace LegalityPredicates;
540 immIdx(0); // Inform verifier imm idx 0 is handled.
541 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
542 }
543
544 /// Use the given action when type indexes 0 and 1 are both in the given list.
545 /// That is, the type pair is in the cartesian product of the list.
546 /// Action should not be an action that requires mutation.
547 LegalizeRuleSet &actionForCartesianProduct(LegalizeAction Action,
548 std::initializer_list<LLT> Types) {
549 using namespace LegalityPredicates;
550 return actionIf(Action, all(typeInSet(typeIdx(0), Types),
551 typeInSet(typeIdx(1), Types)));
552 }
553 /// Use the given action when type indexes 0 and 1 are both in their
554 /// respective lists.
555 /// That is, the type pair is in the cartesian product of the lists
556 /// Action should not be an action that requires mutation.
558 actionForCartesianProduct(LegalizeAction Action,
559 std::initializer_list<LLT> Types0,
560 std::initializer_list<LLT> Types1) {
561 using namespace LegalityPredicates;
562 return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
563 typeInSet(typeIdx(1), Types1)));
564 }
565 /// Use the given action when type indexes 0, 1, and 2 are all in their
566 /// respective lists.
567 /// That is, the type triple is in the cartesian product of the lists
568 /// Action should not be an action that requires mutation.
569 LegalizeRuleSet &actionForCartesianProduct(
570 LegalizeAction Action, std::initializer_list<LLT> Types0,
571 std::initializer_list<LLT> Types1, std::initializer_list<LLT> Types2) {
572 using namespace LegalityPredicates;
573 return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
574 all(typeInSet(typeIdx(1), Types1),
575 typeInSet(typeIdx(2), Types2))));
576 }
577
578public:
579 LegalizeRuleSet() = default;
580
581 bool isAliasedByAnother() { return IsAliasedByAnother; }
582 void setIsAliasedByAnother() { IsAliasedByAnother = true; }
583 void aliasTo(unsigned Opcode) {
584 assert((AliasOf == 0 || AliasOf == Opcode) &&
585 "Opcode is already aliased to another opcode");
586 assert(Rules.empty() && "Aliasing will discard rules");
587 AliasOf = Opcode;
588 }
589 unsigned getAlias() const { return AliasOf; }
590
591 unsigned immIdx(unsigned ImmIdx) {
594 "Imm Index is out of bounds");
595#ifndef NDEBUG
596 ImmIdxsCovered.set(ImmIdx);
597#endif
598 return ImmIdx;
599 }
600
601 /// The instruction is legal if predicate is true.
603 // We have no choice but conservatively assume that the free-form
604 // user-provided Predicate properly handles all type indices:
605 markAllIdxsAsCovered();
606 return actionIf(LegalizeAction::Legal, Predicate);
607 }
608 /// The instruction is legal when type index 0 is any type in the given list.
609 LegalizeRuleSet &legalFor(std::initializer_list<LLT> Types) {
610 return actionFor(LegalizeAction::Legal, Types);
611 }
612 LegalizeRuleSet &legalFor(bool Pred, std::initializer_list<LLT> Types) {
613 if (!Pred)
614 return *this;
615 return actionFor(LegalizeAction::Legal, Types);
616 }
617 /// The instruction is legal when type indexes 0 and 1 is any type pair in the
618 /// given list.
619 LegalizeRuleSet &legalFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
620 return actionFor(LegalizeAction::Legal, Types);
621 }
623 std::initializer_list<std::pair<LLT, LLT>> Types) {
624 if (!Pred)
625 return *this;
626 return actionFor(LegalizeAction::Legal, Types);
627 }
629 legalFor(bool Pred, std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
630 if (!Pred)
631 return *this;
632 return actionFor(LegalizeAction::Legal, Types);
633 }
634 /// The instruction is legal when type index 0 is any type in the given list
635 /// and imm index 0 is anything.
636 LegalizeRuleSet &legalForTypeWithAnyImm(std::initializer_list<LLT> Types) {
637 markAllIdxsAsCovered();
638 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
639 }
640
642 std::initializer_list<std::pair<LLT, LLT>> Types) {
643 markAllIdxsAsCovered();
644 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
645 }
646
647 /// The instruction is legal when type indexes 0 and 1 along with the memory
648 /// size and minimum alignment is any type and size tuple in the given list.
650 std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
651 TypesAndMemDesc) {
652 return actionIf(LegalizeAction::Legal,
654 typeIdx(0), typeIdx(1), /*MMOIdx*/ 0, TypesAndMemDesc));
655 }
657 bool Pred, std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
658 TypesAndMemDesc) {
659 if (!Pred)
660 return *this;
661 return actionIf(LegalizeAction::Legal,
663 typeIdx(0), typeIdx(1), /*MMOIdx=*/0, TypesAndMemDesc));
664 }
665 /// The instruction is legal when type indexes 0 and 1 are both in the given
666 /// list. That is, the type pair is in the cartesian product of the list.
667 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types) {
668 return actionForCartesianProduct(LegalizeAction::Legal, Types);
669 }
670 /// The instruction is legal when type indexes 0 and 1 are both their
671 /// respective lists.
672 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
673 std::initializer_list<LLT> Types1) {
674 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
675 }
676 /// The instruction is legal when type indexes 0, 1, and 2 are both their
677 /// respective lists.
678 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
679 std::initializer_list<LLT> Types1,
680 std::initializer_list<LLT> Types2) {
681 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1,
682 Types2);
683 }
684
686 using namespace LegalizeMutations;
687 markAllIdxsAsCovered();
688 return actionIf(LegalizeAction::Legal, always);
689 }
690
691 /// The specified type index is coerced if predicate is true.
694 // We have no choice but conservatively assume that lowering with a
695 // free-form user provided Predicate properly handles all type indices:
696 markAllIdxsAsCovered();
697 return actionIf(LegalizeAction::Bitcast, Predicate, Mutation);
698 }
699
700 /// The instruction is lowered.
702 using namespace LegalizeMutations;
703 // We have no choice but conservatively assume that predicate-less lowering
704 // properly handles all type indices by design:
705 markAllIdxsAsCovered();
706 return actionIf(LegalizeAction::Lower, always);
707 }
708 /// The instruction is lowered if predicate is true. Keep type index 0 as the
709 /// same type.
711 using namespace LegalizeMutations;
712 // We have no choice but conservatively assume that lowering with a
713 // free-form user provided Predicate properly handles all type indices:
714 markAllIdxsAsCovered();
715 return actionIf(LegalizeAction::Lower, Predicate);
716 }
717 /// The instruction is lowered if predicate is true.
720 // We have no choice but conservatively assume that lowering with a
721 // free-form user provided Predicate properly handles all type indices:
722 markAllIdxsAsCovered();
723 return actionIf(LegalizeAction::Lower, Predicate, Mutation);
724 }
725 /// The instruction is lowered when type index 0 is any type in the given
726 /// list. Keep type index 0 as the same type.
727 LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types) {
728 return actionFor(LegalizeAction::Lower, Types);
729 }
730 /// The instruction is lowered when type index 0 is any type in the given
731 /// list.
732 LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types,
734 return actionFor(LegalizeAction::Lower, Types, Mutation);
735 }
736 /// The instruction is lowered when type indexes 0 and 1 is any type pair in
737 /// the given list. Keep type index 0 as the same type.
738 LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
739 return actionFor(LegalizeAction::Lower, Types);
740 }
741 /// The instruction is lowered when type indexes 0 and 1 is any type pair in
742 /// the given list, provided Predicate pred is true.
744 std::initializer_list<std::pair<LLT, LLT>> Types) {
745 if (!Pred)
746 return *this;
747 return actionFor(LegalizeAction::Lower, Types);
748 }
749 /// The instruction is lowered when type indexes 0 and 1 is any type pair in
750 /// the given list.
751 LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types,
753 return actionFor(LegalizeAction::Lower, Types, Mutation);
754 }
755 /// The instruction is lowered when type indexes 0 and 1 are both in their
756 /// respective lists.
757 LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
758 std::initializer_list<LLT> Types1) {
759 using namespace LegalityPredicates;
760 return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1);
761 }
762 /// The instruction is lowered when type indexes 0, 1, and 2 are all in
763 /// their respective lists.
764 LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
765 std::initializer_list<LLT> Types1,
766 std::initializer_list<LLT> Types2) {
767 using namespace LegalityPredicates;
768 return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1,
769 Types2);
770 }
771
772 /// The instruction is emitted as a library call.
774 using namespace LegalizeMutations;
775 // We have no choice but conservatively assume that predicate-less lowering
776 // properly handles all type indices by design:
777 markAllIdxsAsCovered();
778 return actionIf(LegalizeAction::Libcall, always);
779 }
780
781 /// Like legalIf, but for the Libcall action.
783 // We have no choice but conservatively assume that a libcall with a
784 // free-form user provided Predicate properly handles all type indices:
785 markAllIdxsAsCovered();
786 return actionIf(LegalizeAction::Libcall, Predicate);
787 }
788 LegalizeRuleSet &libcallFor(std::initializer_list<LLT> Types) {
789 return actionFor(LegalizeAction::Libcall, Types);
790 }
791 LegalizeRuleSet &libcallFor(bool Pred, std::initializer_list<LLT> Types) {
792 if (!Pred)
793 return *this;
794 return actionFor(LegalizeAction::Libcall, Types);
795 }
797 libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
798 return actionFor(LegalizeAction::Libcall, Types);
799 }
801 libcallFor(bool Pred, std::initializer_list<std::pair<LLT, LLT>> Types) {
802 if (!Pred)
803 return *this;
804 return actionFor(LegalizeAction::Libcall, Types);
805 }
807 libcallForCartesianProduct(std::initializer_list<LLT> Types) {
808 return actionForCartesianProduct(LegalizeAction::Libcall, Types);
809 }
811 libcallForCartesianProduct(std::initializer_list<LLT> Types0,
812 std::initializer_list<LLT> Types1) {
813 return actionForCartesianProduct(LegalizeAction::Libcall, Types0, Types1);
814 }
815
816 /// Widen the scalar to the one selected by the mutation if the predicate is
817 /// true.
820 // We have no choice but conservatively assume that an action with a
821 // free-form user provided Predicate properly handles all type indices:
822 markAllIdxsAsCovered();
823 return actionIf(LegalizeAction::WidenScalar, Predicate, Mutation);
824 }
825 /// Widen the scalar, specified in mutation, when type index 0 is any type in
826 /// the given list.
827 LegalizeRuleSet &widenScalarFor(std::initializer_list<LLT> Types,
829 return actionFor(LegalizeAction::WidenScalar, Types, Mutation);
830 }
831 /// Widen the scalar, specified in mutation, when type indexes 0 and 1 is any
832 /// type pair in the given list.
834 widenScalarFor(std::initializer_list<std::pair<LLT, LLT>> Types,
836 return actionFor(LegalizeAction::WidenScalar, Types, Mutation);
837 }
838
839 /// Narrow the scalar to the one selected by the mutation if the predicate is
840 /// true.
843 // We have no choice but conservatively assume that an action with a
844 // free-form user provided Predicate properly handles all type indices:
845 markAllIdxsAsCovered();
846 return actionIf(LegalizeAction::NarrowScalar, Predicate, Mutation);
847 }
848 /// Narrow the scalar, specified in mutation, when type indexes 0 and 1 is any
849 /// type pair in the given list.
851 narrowScalarFor(std::initializer_list<std::pair<LLT, LLT>> Types,
853 return actionFor(LegalizeAction::NarrowScalar, Types, Mutation);
854 }
855
856 /// Add more elements to reach the type selected by the mutation if the
857 /// predicate is true.
860 // We have no choice but conservatively assume that an action with a
861 // free-form user provided Predicate properly handles all type indices:
862 markAllIdxsAsCovered();
863 return actionIf(LegalizeAction::MoreElements, Predicate, Mutation);
864 }
865 /// Remove elements to reach the type selected by the mutation if the
866 /// predicate is true.
869 // We have no choice but conservatively assume that an action with a
870 // free-form user provided Predicate properly handles all type indices:
871 markAllIdxsAsCovered();
872 return actionIf(LegalizeAction::FewerElements, Predicate, Mutation);
873 }
874
875 /// The instruction is unsupported.
877 markAllIdxsAsCovered();
878 return actionIf(LegalizeAction::Unsupported, always);
879 }
881 return actionIf(LegalizeAction::Unsupported, Predicate);
882 }
883
884 LegalizeRuleSet &unsupportedFor(std::initializer_list<LLT> Types) {
885 return actionFor(LegalizeAction::Unsupported, Types);
886 }
887
889 return actionIf(LegalizeAction::Unsupported,
891 }
892
893 /// Lower a memory operation if the memory size, rounded to bytes, is not a
894 /// power of 2. For example, this will not trigger for s1 or s7, but will for
895 /// s24.
897 return actionIf(LegalizeAction::Lower,
899 }
900
901 /// Lower a memory operation if the memory access size is not a round power of
902 /// 2 byte size. This is stricter than lowerIfMemSizeNotPow2, and more likely
903 /// what you want (e.g. this will lower s1, s7 and s24).
905 return actionIf(LegalizeAction::Lower,
907 }
908
910 // We have no choice but conservatively assume that a custom action with a
911 // free-form user provided Predicate properly handles all type indices:
912 markAllIdxsAsCovered();
913 return actionIf(LegalizeAction::Custom, Predicate);
914 }
915 LegalizeRuleSet &customFor(std::initializer_list<LLT> Types) {
916 return actionFor(LegalizeAction::Custom, Types);
917 }
918 LegalizeRuleSet &customFor(bool Pred, std::initializer_list<LLT> Types) {
919 if (!Pred)
920 return *this;
921 return actionFor(LegalizeAction::Custom, Types);
922 }
923
924 /// The instruction is custom when type indexes 0 and 1 is any type pair in
925 /// the given list.
926 LegalizeRuleSet &customFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
927 return actionFor(LegalizeAction::Custom, Types);
928 }
930 std::initializer_list<std::pair<LLT, LLT>> Types) {
931 if (!Pred)
932 return *this;
933 return actionFor(LegalizeAction::Custom, Types);
934 }
935
936 LegalizeRuleSet &customForCartesianProduct(std::initializer_list<LLT> Types) {
937 return actionForCartesianProduct(LegalizeAction::Custom, Types);
938 }
939 /// The instruction is custom when type indexes 0 and 1 are both in their
940 /// respective lists.
942 customForCartesianProduct(std::initializer_list<LLT> Types0,
943 std::initializer_list<LLT> Types1) {
944 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
945 }
946 /// The instruction is custom when type indexes 0, 1, and 2 are all in
947 /// their respective lists.
949 customForCartesianProduct(std::initializer_list<LLT> Types0,
950 std::initializer_list<LLT> Types1,
951 std::initializer_list<LLT> Types2) {
952 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1,
953 Types2);
954 }
955
956 /// The instruction is custom when the predicate is true and type indexes 0
957 /// and 1 are all in their respective lists.
959 customForCartesianProduct(bool Pred, std::initializer_list<LLT> Types0,
960 std::initializer_list<LLT> Types1) {
961 if (!Pred)
962 return *this;
963 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
964 }
965
966 /// Unconditionally custom lower.
968 return customIf(always);
969 }
970
971 /// Widen the scalar to the next power of two that is at least MinSize.
972 /// No effect if the type is a power of two, except if the type is smaller
973 /// than MinSize, or if the type is a vector type.
975 unsigned MinSize = 0) {
976 using namespace LegalityPredicates;
977 return actionIf(
978 LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
980 }
981
982 /// Widen the scalar to the next multiple of Size. No effect if the
983 /// type is not a scalar or is a multiple of Size.
985 unsigned Size) {
986 using namespace LegalityPredicates;
987 return actionIf(
988 LegalizeAction::WidenScalar, sizeNotMultipleOf(typeIdx(TypeIdx), Size),
990 }
991
992 /// Widen the scalar or vector element type to the next power of two that is
993 /// at least MinSize. No effect if the scalar size is a power of two.
995 unsigned MinSize = 0) {
996 using namespace LegalityPredicates;
997 return actionIf(
998 LegalizeAction::WidenScalar, scalarOrEltSizeNotPow2(typeIdx(TypeIdx)),
1000 }
1001
1002 /// Widen the scalar or vector element type to the next power of two that is
1003 /// at least MinSize. No effect if the scalar size is a power of two.
1005 unsigned MinSize = 0) {
1006 using namespace LegalityPredicates;
1007 return actionIf(
1008 LegalizeAction::WidenScalar,
1009 any(scalarOrEltNarrowerThan(TypeIdx, MinSize),
1010 scalarOrEltSizeNotPow2(typeIdx(TypeIdx))),
1012 }
1013
1015 using namespace LegalityPredicates;
1016 return actionIf(LegalizeAction::NarrowScalar, isScalar(typeIdx(TypeIdx)),
1017 Mutation);
1018 }
1019
1020 LegalizeRuleSet &scalarize(unsigned TypeIdx) {
1021 using namespace LegalityPredicates;
1022 return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)),
1024 }
1025
1027 using namespace LegalityPredicates;
1028 return actionIf(LegalizeAction::FewerElements,
1029 all(Predicate, isVector(typeIdx(TypeIdx))),
1031 }
1032
1033 /// Ensure the scalar or element is at least as wide as Ty.
1034 LegalizeRuleSet &minScalarOrElt(unsigned TypeIdx, const LLT Ty) {
1035 using namespace LegalityPredicates;
1036 using namespace LegalizeMutations;
1037 return actionIf(LegalizeAction::WidenScalar,
1038 scalarOrEltNarrowerThan(TypeIdx, Ty.getScalarSizeInBits()),
1039 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1040 }
1041
1042 /// Ensure the scalar or element is at least as wide as Ty.
1044 unsigned TypeIdx, const LLT Ty) {
1045 using namespace LegalityPredicates;
1046 using namespace LegalizeMutations;
1047 return actionIf(LegalizeAction::WidenScalar,
1048 all(Predicate, scalarOrEltNarrowerThan(
1049 TypeIdx, Ty.getScalarSizeInBits())),
1050 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1051 }
1052
1053 /// Ensure the vector size is at least as wide as VectorSize by promoting the
1054 /// element.
1056 unsigned VectorSize) {
1057 using namespace LegalityPredicates;
1058 using namespace LegalizeMutations;
1059 return actionIf(
1060 LegalizeAction::WidenScalar,
1061 [=](const LegalityQuery &Query) {
1062 const LLT VecTy = Query.Types[TypeIdx];
1063 return VecTy.isFixedVector() && VecTy.getSizeInBits() < VectorSize;
1064 },
1065 [=](const LegalityQuery &Query) {
1066 const LLT VecTy = Query.Types[TypeIdx];
1067 unsigned NumElts = VecTy.getNumElements();
1068 unsigned MinSize = VectorSize / NumElts;
1069 LLT NewTy = LLT::fixed_vector(
1070 NumElts, VecTy.getElementType().changeElementSize(MinSize));
1071 return std::make_pair(TypeIdx, NewTy);
1072 });
1073 }
1074
1075 /// Ensure the scalar is at least as wide as Ty.
1076 LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT Ty) {
1077 using namespace LegalityPredicates;
1078 using namespace LegalizeMutations;
1079 return actionIf(LegalizeAction::WidenScalar,
1080 scalarNarrowerThan(TypeIdx, Ty.getSizeInBits()),
1081 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1082 }
1083 LegalizeRuleSet &minScalar(bool Pred, unsigned TypeIdx, const LLT Ty) {
1084 if (!Pred)
1085 return *this;
1086 return minScalar(TypeIdx, Ty);
1087 }
1088
1089 /// Ensure the scalar is at least as wide as Ty if condition is met.
1091 const LLT Ty) {
1092 using namespace LegalityPredicates;
1093 using namespace LegalizeMutations;
1094 return actionIf(
1095 LegalizeAction::WidenScalar,
1096 [=](const LegalityQuery &Query) {
1097 const LLT QueryTy = Query.Types[TypeIdx];
1098 return QueryTy.isScalar() &&
1099 QueryTy.getSizeInBits() < Ty.getSizeInBits() &&
1100 Predicate(Query);
1101 },
1102 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1103 }
1104
1105 /// Ensure the scalar is at most as wide as Ty.
1106 LegalizeRuleSet &maxScalarOrElt(unsigned TypeIdx, const LLT Ty) {
1107 using namespace LegalityPredicates;
1108 using namespace LegalizeMutations;
1109 return actionIf(LegalizeAction::NarrowScalar,
1110 scalarOrEltWiderThan(TypeIdx, Ty.getScalarSizeInBits()),
1111 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1112 }
1113
1114 /// Ensure the scalar is at most as wide as Ty.
1115 LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT Ty) {
1116 using namespace LegalityPredicates;
1117 using namespace LegalizeMutations;
1118 return actionIf(LegalizeAction::NarrowScalar,
1119 scalarWiderThan(TypeIdx, Ty.getSizeInBits()),
1120 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1121 }
1122
1123 /// Conditionally limit the maximum size of the scalar.
1124 /// For example, when the maximum size of one type depends on the size of
1125 /// another such as extracting N bits from an M bit container.
1127 const LLT Ty) {
1128 using namespace LegalityPredicates;
1129 using namespace LegalizeMutations;
1130 return actionIf(
1131 LegalizeAction::NarrowScalar,
1132 [=](const LegalityQuery &Query) {
1133 const LLT QueryTy = Query.Types[TypeIdx];
1134 return QueryTy.isScalar() &&
1135 QueryTy.getSizeInBits() > Ty.getSizeInBits() &&
1136 Predicate(Query);
1137 },
1138 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1139 }
1140
1141 /// Limit the range of scalar sizes to MinTy and MaxTy.
1142 LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT MinTy,
1143 const LLT MaxTy) {
1144 assert(MinTy.isScalar() && MaxTy.isScalar() && "Expected scalar types");
1145 return minScalar(TypeIdx, MinTy).maxScalar(TypeIdx, MaxTy);
1146 }
1147
1148 LegalizeRuleSet &clampScalar(bool Pred, unsigned TypeIdx, const LLT MinTy,
1149 const LLT MaxTy) {
1150 if (!Pred)
1151 return *this;
1152 return clampScalar(TypeIdx, MinTy, MaxTy);
1153 }
1154
1155 /// Limit the range of scalar sizes to MinTy and MaxTy.
1156 LegalizeRuleSet &clampScalarOrElt(unsigned TypeIdx, const LLT MinTy,
1157 const LLT MaxTy) {
1158 return minScalarOrElt(TypeIdx, MinTy).maxScalarOrElt(TypeIdx, MaxTy);
1159 }
1160
1161 /// Widen the scalar to match the size of another.
1162 LegalizeRuleSet &minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx) {
1163 typeIdx(TypeIdx);
1164 return actionIf(
1165 LegalizeAction::WidenScalar,
1166 [=](const LegalityQuery &Query) {
1167 return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
1168 Query.Types[TypeIdx].getSizeInBits();
1169 },
1170 LegalizeMutations::changeElementSizeTo(TypeIdx, LargeTypeIdx));
1171 }
1172
1173 /// Narrow the scalar to match the size of another.
1174 LegalizeRuleSet &maxScalarSameAs(unsigned TypeIdx, unsigned NarrowTypeIdx) {
1175 typeIdx(TypeIdx);
1176 return actionIf(
1177 LegalizeAction::NarrowScalar,
1178 [=](const LegalityQuery &Query) {
1179 return Query.Types[NarrowTypeIdx].getScalarSizeInBits() <
1180 Query.Types[TypeIdx].getSizeInBits();
1181 },
1182 LegalizeMutations::changeElementSizeTo(TypeIdx, NarrowTypeIdx));
1183 }
1184
1185 /// Change the type \p TypeIdx to have the same scalar size as type \p
1186 /// SameSizeIdx.
1187 LegalizeRuleSet &scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx) {
1188 return minScalarSameAs(TypeIdx, SameSizeIdx)
1189 .maxScalarSameAs(TypeIdx, SameSizeIdx);
1190 }
1191
1192 /// Conditionally widen the scalar or elt to match the size of another.
1194 unsigned TypeIdx, unsigned LargeTypeIdx) {
1195 typeIdx(TypeIdx);
1196 return widenScalarIf(
1197 [=](const LegalityQuery &Query) {
1198 return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
1199 Query.Types[TypeIdx].getScalarSizeInBits() &&
1200 Predicate(Query);
1201 },
1202 [=](const LegalityQuery &Query) {
1203 LLT T = Query.Types[TypeIdx].changeElementSize(
1204 Query.Types[LargeTypeIdx].getScalarSizeInBits());
1205 return std::make_pair(TypeIdx, T);
1206 });
1207 }
1208
1209 /// Conditionally narrow the scalar or elt to match the size of another.
1211 unsigned TypeIdx,
1212 unsigned SmallTypeIdx) {
1213 typeIdx(TypeIdx);
1214 return narrowScalarIf(
1215 [=](const LegalityQuery &Query) {
1216 return Query.Types[SmallTypeIdx].getScalarSizeInBits() <
1217 Query.Types[TypeIdx].getScalarSizeInBits() &&
1218 Predicate(Query);
1219 },
1220 [=](const LegalityQuery &Query) {
1221 LLT T = Query.Types[SmallTypeIdx];
1222 return std::make_pair(TypeIdx, T);
1223 });
1224 }
1225
1226 /// Add more elements to the vector to reach the next power of two.
1227 /// No effect if the type is not a vector or the element count is a power of
1228 /// two.
1230 using namespace LegalityPredicates;
1231 return actionIf(LegalizeAction::MoreElements,
1232 numElementsNotPow2(typeIdx(TypeIdx)),
1234 }
1235
1236 /// Limit the number of elements in EltTy vectors to at least MinElements.
1237 LegalizeRuleSet &clampMinNumElements(unsigned TypeIdx, const LLT EltTy,
1238 unsigned MinElements) {
1239 // Mark the type index as covered:
1240 typeIdx(TypeIdx);
1241 return actionIf(
1242 LegalizeAction::MoreElements,
1243 [=](const LegalityQuery &Query) {
1244 LLT VecTy = Query.Types[TypeIdx];
1245 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1246 VecTy.getNumElements() < MinElements;
1247 },
1248 [=](const LegalityQuery &Query) {
1249 LLT VecTy = Query.Types[TypeIdx];
1250 return std::make_pair(
1251 TypeIdx, LLT::fixed_vector(MinElements, VecTy.getElementType()));
1252 });
1253 }
1254
1255 /// Set number of elements to nearest larger multiple of NumElts.
1256 LegalizeRuleSet &alignNumElementsTo(unsigned TypeIdx, const LLT EltTy,
1257 unsigned NumElts) {
1258 typeIdx(TypeIdx);
1259 return actionIf(
1260 LegalizeAction::MoreElements,
1261 [=](const LegalityQuery &Query) {
1262 LLT VecTy = Query.Types[TypeIdx];
1263 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1264 (VecTy.getNumElements() % NumElts != 0);
1265 },
1266 [=](const LegalityQuery &Query) {
1267 LLT VecTy = Query.Types[TypeIdx];
1268 unsigned NewSize = alignTo(VecTy.getNumElements(), NumElts);
1269 return std::make_pair(
1270 TypeIdx, LLT::fixed_vector(NewSize, VecTy.getElementType()));
1271 });
1272 }
1273
1274 /// Limit the number of elements in EltTy vectors to at most MaxElements.
1275 LegalizeRuleSet &clampMaxNumElements(unsigned TypeIdx, const LLT EltTy,
1276 unsigned MaxElements) {
1277 // Mark the type index as covered:
1278 typeIdx(TypeIdx);
1279 return actionIf(
1280 LegalizeAction::FewerElements,
1281 [=](const LegalityQuery &Query) {
1282 LLT VecTy = Query.Types[TypeIdx];
1283 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1284 VecTy.getNumElements() > MaxElements;
1285 },
1286 [=](const LegalityQuery &Query) {
1287 LLT VecTy = Query.Types[TypeIdx];
1288 LLT NewTy = LLT::scalarOrVector(ElementCount::getFixed(MaxElements),
1289 VecTy.getElementType());
1290 return std::make_pair(TypeIdx, NewTy);
1291 });
1292 }
1293 /// Limit the number of elements for the given vectors to at least MinTy's
1294 /// number of elements and at most MaxTy's number of elements.
1295 ///
1296 /// No effect if the type is not a vector or does not have the same element
1297 /// type as the constraints.
1298 /// The element type of MinTy and MaxTy must match.
1299 LegalizeRuleSet &clampNumElements(unsigned TypeIdx, const LLT MinTy,
1300 const LLT MaxTy) {
1301 assert(MinTy.getElementType() == MaxTy.getElementType() &&
1302 "Expected element types to agree");
1303
1304 assert((!MinTy.isScalableVector() && !MaxTy.isScalableVector()) &&
1305 "Unexpected scalable vectors");
1306
1307 const LLT EltTy = MinTy.getElementType();
1308 return clampMinNumElements(TypeIdx, EltTy, MinTy.getNumElements())
1309 .clampMaxNumElements(TypeIdx, EltTy, MaxTy.getNumElements());
1310 }
1311
1312 /// Express \p EltTy vectors strictly using vectors with \p NumElts elements
1313 /// (or scalars when \p NumElts equals 1).
1314 /// First pad with undef elements to nearest larger multiple of \p NumElts.
1315 /// Then perform split with all sub-instructions having the same type.
1316 /// Using clampMaxNumElements (non-strict) can result in leftover instruction
1317 /// with different type (fewer elements then \p NumElts or scalar).
1318 /// No effect if the type is not a vector.
1319 LegalizeRuleSet &clampMaxNumElementsStrict(unsigned TypeIdx, const LLT EltTy,
1320 unsigned NumElts) {
1321 return alignNumElementsTo(TypeIdx, EltTy, NumElts)
1322 .clampMaxNumElements(TypeIdx, EltTy, NumElts);
1323 }
1324
1325 /// Check if there is no type index which is obviously not handled by the
1326 /// LegalizeRuleSet in any way at all.
1327 /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
1328 LLVM_ABI bool verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const;
1329 /// Check if there is no imm index which is obviously not handled by the
1330 /// LegalizeRuleSet in any way at all.
1331 /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
1332 LLVM_ABI bool verifyImmIdxsCoverage(unsigned NumImmIdxs) const;
1333
1334 /// Apply the ruleset to the given LegalityQuery.
1335 LLVM_ABI LegalizeActionStep apply(const LegalityQuery &Query) const;
1336};
1337
1339public:
1340 virtual ~LegalizerInfo() = default;
1341
1342 unsigned getOpcodeIdxForOpcode(unsigned Opcode) const;
1343 unsigned getActionDefinitionsIdx(unsigned Opcode) const;
1344
1345 /// Perform simple self-diagnostic and assert if there is anything obviously
1346 /// wrong with the actions set up.
1347 void verify(const MCInstrInfo &MII) const;
1348
1349 /// Get the action definitions for the given opcode. Use this to run a
1350 /// LegalityQuery through the definitions.
1351 const LegalizeRuleSet &getActionDefinitions(unsigned Opcode) const;
1352
1353 /// Get the action definition builder for the given opcode. Use this to define
1354 /// the action definitions.
1355 ///
1356 /// It is an error to request an opcode that has already been requested by the
1357 /// multiple-opcode variant.
1359
1360 /// Get the action definition builder for the given set of opcodes. Use this
1361 /// to define the action definitions for multiple opcodes at once. The first
1362 /// opcode given will be considered the representative opcode and will hold
1363 /// the definitions whereas the other opcodes will be configured to refer to
1364 /// the representative opcode. This lowers memory requirements and very
1365 /// slightly improves performance.
1366 ///
1367 /// It would be very easy to introduce unexpected side-effects as a result of
1368 /// this aliasing if it were permitted to request different but intersecting
1369 /// sets of opcodes but that is difficult to keep track of. It is therefore an
1370 /// error to request the same opcode twice using this API, to request an
1371 /// opcode that already has definitions, or to use the single-opcode API on an
1372 /// opcode that has already been requested by this API.
1374 getActionDefinitionsBuilder(std::initializer_list<unsigned> Opcodes);
1375 void aliasActionDefinitions(unsigned OpcodeTo, unsigned OpcodeFrom);
1376
1377 /// Determine what action should be taken to legalize the described
1378 /// instruction. Requires computeTables to have been called.
1379 ///
1380 /// \returns a description of the next legalization step to perform.
1381 LegalizeActionStep getAction(const LegalityQuery &Query) const;
1382
1383 /// Determine what action should be taken to legalize the given generic
1384 /// instruction.
1385 ///
1386 /// \returns a description of the next legalization step to perform.
1388 const MachineRegisterInfo &MRI) const;
1389
1390 bool isLegal(const LegalityQuery &Query) const {
1391 return getAction(Query).Action == LegalizeAction::Legal;
1392 }
1393
1394 bool isLegalOrCustom(const LegalityQuery &Query) const {
1395 auto Action = getAction(Query).Action;
1396 return Action == LegalizeAction::Legal || Action == LegalizeAction::Custom;
1397 }
1398
1399 bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
1400 bool isLegalOrCustom(const MachineInstr &MI,
1401 const MachineRegisterInfo &MRI) const;
1402
1403 /// Called for instructions with the Custom LegalizationAction.
1405 LostDebugLocObserver &LocObserver) const {
1406 llvm_unreachable("must implement this if custom action is used");
1407 }
1408
1409 /// \returns true if MI is either legal or has been legalized and false if not
1410 /// legal.
1411 /// Return true if MI is either legal or has been legalized and false
1412 /// if not legal.
1414 MachineInstr &MI) const {
1415 return true;
1416 }
1417
1418 /// Return the opcode (SEXT/ZEXT/ANYEXT) that should be performed while
1419 /// widening a constant of type SmallTy which targets can override.
1420 /// For eg, the DAG does (SmallTy.isByteSized() ? G_SEXT : G_ZEXT) which
1421 /// will be the default.
1422 virtual unsigned getExtOpcodeForWideningConstant(LLT SmallTy) const;
1423
1424private:
1425 static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
1426 static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
1427
1428 LegalizeRuleSet RulesForOpcode[LastOp - FirstOp + 1];
1429};
1430
1431#ifndef NDEBUG
1432/// Checks that MIR is fully legal, returns an illegal instruction if it's not,
1433/// nullptr otherwise
1434const MachineInstr *machineFunctionIsIllegal(const MachineFunction &MF);
1435#endif
1436
1437} // end namespace llvm.
1438
1439#endif // LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Atomic ordering constants.
#define LLVM_ABI
Definition Compiler.h:215
static MaybeAlign getAlign(Value *Ptr)
IRTranslator LLVM IR MI
Implement a low-level type suitable for MachineInstr level instruction selection.
#define T
nvptx lower args
#define P(N)
ppc ctr loops verify
PowerPC VSX FMA Mutation
This file implements the SmallBitVector class.
This file defines the SmallVector class.
Value * RHS
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:309
constexpr bool isScalableVector() const
Returns true if the LLT is a scalable vector.
constexpr bool isScalar() const
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
static constexpr LLT scalarOrVector(ElementCount EC, LLT ScalarTy)
LLT changeElementSize(unsigned NewEltSize) const
If this type is a vector, return a vector with the same number of elements but the new element size.
LegalizeRuleSet & minScalar(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at least as wide as Ty.
LegalizeRuleSet & clampScalar(bool Pred, unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
LegalizeRuleSet & maxScalarSameAs(unsigned TypeIdx, unsigned NarrowTypeIdx)
Narrow the scalar to match the size of another.
LegalizeRuleSet & widenScalarOrEltToNextPow2OrMinSize(unsigned TypeIdx, unsigned MinSize=0)
Widen the scalar or vector element type to the next power of two that is at least MinSize.
LegalizeRuleSet & customForCartesianProduct(bool Pred, std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is custom when the predicate is true and type indexes 0 and 1 are all in their respec...
LegalizeRuleSet & legalFor(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list.
LegalizeRuleSet & lowerFor(bool Pred, std::initializer_list< std::pair< LLT, LLT > > Types)
The instruction is lowered when type indexes 0 and 1 is any type pair in the given list,...
LegalizeRuleSet & maxScalarEltSameAsIf(LegalityPredicate Predicate, unsigned TypeIdx, unsigned SmallTypeIdx)
Conditionally narrow the scalar or elt to match the size of another.
LegalizeRuleSet & unsupported()
The instruction is unsupported.
LegalizeRuleSet & legalFor(bool Pred, std::initializer_list< std::tuple< LLT, LLT, LLT > > Types)
LegalizeRuleSet & scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx)
Change the type TypeIdx to have the same scalar size as type SameSizeIdx.
LegalizeRuleSet & fewerElementsIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Remove elements to reach the type selected by the mutation if the predicate is true.
LegalizeRuleSet & clampScalarOrElt(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
void aliasTo(unsigned Opcode)
LegalizeRuleSet & bitcastIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
The specified type index is coerced if predicate is true.
LegalizeRuleSet & libcall()
The instruction is emitted as a library call.
LegalizeRuleSet & libcallFor(std::initializer_list< LLT > Types)
LLVM_ABI bool verifyImmIdxsCoverage(unsigned NumImmIdxs) const
Check if there is no imm index which is obviously not handled by the LegalizeRuleSet in any way at al...
LegalizeRuleSet & maxScalar(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at most as wide as Ty.
LegalizeRuleSet & minScalarOrElt(unsigned TypeIdx, const LLT Ty)
Ensure the scalar or element is at least as wide as Ty.
LegalizeRuleSet & clampMaxNumElements(unsigned TypeIdx, const LLT EltTy, unsigned MaxElements)
Limit the number of elements in EltTy vectors to at most MaxElements.
LegalizeRuleSet & clampMinNumElements(unsigned TypeIdx, const LLT EltTy, unsigned MinElements)
Limit the number of elements in EltTy vectors to at least MinElements.
LegalizeRuleSet & libcallForCartesianProduct(std::initializer_list< LLT > Types)
LegalizeRuleSet & unsupportedFor(std::initializer_list< LLT > Types)
LegalizeRuleSet & legalFor(bool Pred, std::initializer_list< LLT > Types)
LegalizeRuleSet & widenVectorEltsToVectorMinSize(unsigned TypeIdx, unsigned VectorSize)
Ensure the vector size is at least as wide as VectorSize by promoting the element.
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is legal when type indexes 0 and 1 are both their respective lists.
LegalizeRuleSet & lowerIfMemSizeNotPow2()
Lower a memory operation if the memory size, rounded to bytes, is not a power of 2.
LegalizeRuleSet & lowerFor(std::initializer_list< LLT > Types, LegalizeMutation Mutation)
The instruction is lowered when type index 0 is any type in the given list.
LegalizeRuleSet & minScalarEltSameAsIf(LegalityPredicate Predicate, unsigned TypeIdx, unsigned LargeTypeIdx)
Conditionally widen the scalar or elt to match the size of another.
LegalizeRuleSet & customForCartesianProduct(std::initializer_list< LLT > Types)
LegalizeRuleSet & lowerIfMemSizeNotByteSizePow2()
Lower a memory operation if the memory access size is not a round power of 2 byte size.
LegalizeRuleSet & widenScalarFor(std::initializer_list< LLT > Types, LegalizeMutation Mutation)
Widen the scalar, specified in mutation, when type index 0 is any type in the given list.
LegalizeRuleSet & minScalar(bool Pred, unsigned TypeIdx, const LLT Ty)
LegalizeRuleSet & moreElementsToNextPow2(unsigned TypeIdx)
Add more elements to the vector to reach the next power of two.
LegalizeRuleSet & customForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is custom when type indexes 0 and 1 are both in their respective lists.
LegalizeRuleSet & legalForTypeWithAnyImm(std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & lowerFor(std::initializer_list< std::pair< LLT, LLT > > Types)
The instruction is lowered when type indexes 0 and 1 is any type pair in the given list.
LegalizeRuleSet & narrowScalarIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Narrow the scalar to the one selected by the mutation if the predicate is true.
LegalizeRuleSet & lower()
The instruction is lowered.
LegalizeRuleSet & moreElementsIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Add more elements to reach the type selected by the mutation if the predicate is true.
LegalizeRuleSet & narrowScalarFor(std::initializer_list< std::pair< LLT, LLT > > Types, LegalizeMutation Mutation)
Narrow the scalar, specified in mutation, when type indexes 0 and 1 is any type pair in the given lis...
LegalizeRuleSet & narrowScalar(unsigned TypeIdx, LegalizeMutation Mutation)
LegalizeRuleSet & customFor(bool Pred, std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & lowerFor(std::initializer_list< LLT > Types)
The instruction is lowered when type index 0 is any type in the given list.
LegalizeRuleSet & scalarizeIf(LegalityPredicate Predicate, unsigned TypeIdx)
LegalizeRuleSet & lowerIf(LegalityPredicate Predicate)
The instruction is lowered if predicate is true.
LegalizeRuleSet & clampScalar(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1, std::initializer_list< LLT > Types2)
The instruction is legal when type indexes 0, 1, and 2 are both their respective lists.
LegalizeRuleSet & alignNumElementsTo(unsigned TypeIdx, const LLT EltTy, unsigned NumElts)
Set number of elements to nearest larger multiple of NumElts.
LegalizeRuleSet & custom()
Unconditionally custom lower.
LegalizeRuleSet & widenScalarFor(std::initializer_list< std::pair< LLT, LLT > > Types, LegalizeMutation Mutation)
Widen the scalar, specified in mutation, when type indexes 0 and 1 is any type pair in the given list...
LegalizeRuleSet & libcallForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
LegalizeRuleSet & clampMaxNumElementsStrict(unsigned TypeIdx, const LLT EltTy, unsigned NumElts)
Express EltTy vectors strictly using vectors with NumElts elements (or scalars when NumElts equals 1)...
LegalizeRuleSet & minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx)
Widen the scalar to match the size of another.
LegalizeRuleSet & unsupportedIf(LegalityPredicate Predicate)
LegalizeRuleSet & minScalarOrEltIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT Ty)
Ensure the scalar or element is at least as wide as Ty.
LegalizeRuleSet & widenScalarIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Widen the scalar to the one selected by the mutation if the predicate is true.
LegalizeRuleSet & libcallFor(std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & customFor(bool Pred, std::initializer_list< LLT > Types)
LegalizeRuleSet & legalForTypeWithAnyImm(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list and imm index 0 is anything.
LegalizeRuleSet & lowerForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1, std::initializer_list< LLT > Types2)
The instruction is lowered when type indexes 0, 1, and 2 are all in their respective lists.
LegalizeRuleSet & legalForTypesWithMemDesc(bool Pred, std::initializer_list< LegalityPredicates::TypePairAndMemDesc > TypesAndMemDesc)
LegalizeRuleSet & legalFor(std::initializer_list< std::pair< LLT, LLT > > Types)
The instruction is legal when type indexes 0 and 1 is any type pair in the given list.
LegalizeRuleSet & libcallFor(bool Pred, std::initializer_list< LLT > Types)
LegalizeRuleSet & libcallFor(bool Pred, std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & alwaysLegal()
LegalizeRuleSet & legalFor(bool Pred, std::initializer_list< std::pair< LLT, LLT > > Types)
unsigned getAlias() const
LegalizeRuleSet & clampNumElements(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the number of elements for the given vectors to at least MinTy's number of elements and at most...
LegalizeRuleSet & unsupportedIfMemSizeNotPow2()
LegalizeRuleSet & maxScalarIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT Ty)
Conditionally limit the maximum size of the scalar.
LegalizeRuleSet & customIf(LegalityPredicate Predicate)
LegalizeRuleSet & customForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1, std::initializer_list< LLT > Types2)
The instruction is custom when type indexes 0, 1, and 2 are all in their respective lists.
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 & lowerForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is lowered when type indexes 0 and 1 are both in their respective lists.
LegalizeRuleSet & lowerIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
The instruction is lowered if predicate is true.
LegalizeRuleSet & legalForTypesWithMemDesc(std::initializer_list< LegalityPredicates::TypePairAndMemDesc > TypesAndMemDesc)
The instruction is legal when type indexes 0 and 1 along with the memory size and minimum alignment i...
LegalizeRuleSet & libcallIf(LegalityPredicate Predicate)
Like legalIf, but for the Libcall action.
LegalizeRuleSet & maxScalarOrElt(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at most as wide as Ty.
LegalizeRuleSet & customFor(std::initializer_list< std::pair< LLT, LLT > > Types)
The instruction is custom when type indexes 0 and 1 is any type pair in the given list.
LegalizeRuleSet & minScalarIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at least as wide as Ty if condition is met.
unsigned immIdx(unsigned ImmIdx)
LLVM_ABI bool verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const
Check if there is no type index which is obviously not handled by the LegalizeRuleSet in any way at a...
LegalizeRuleSet & widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned MinSize=0)
Widen the scalar or vector element type to the next power of two that is at least MinSize.
LLVM_ABI LegalizeActionStep apply(const LegalityQuery &Query) const
Apply the ruleset to the given LegalityQuery.
LegalizeRuleSet & lowerFor(std::initializer_list< std::pair< LLT, LLT > > Types, LegalizeMutation Mutation)
The instruction is lowered when type indexes 0 and 1 is any type pair in the given list.
LegalizeRuleSet & legalIf(LegalityPredicate Predicate)
The instruction is legal if predicate is true.
LegalizeRuleSet & customFor(std::initializer_list< LLT > Types)
LegalizeRuleSet & widenScalarToNextMultipleOf(unsigned TypeIdx, unsigned Size)
Widen the scalar to the next multiple of Size.
A single rule in a legalizer info ruleset.
std::pair< unsigned, LLT > determineMutation(const LegalityQuery &Query) const
Determine the change to make.
bool match(const LegalityQuery &Query) const
Test whether the LegalityQuery matches.
LegalizeRule(LegalityPredicate Predicate, LegalizeAction Action, LegalizeMutation Mutation=nullptr)
LegalizeAction getAction() const
const LegalizeRuleSet & getActionDefinitions(unsigned Opcode) const
Get the action definitions for the given opcode.
virtual ~LegalizerInfo()=default
LegalizeRuleSet & getActionDefinitionsBuilder(unsigned Opcode)
Get the action definition builder for the given opcode.
bool isLegalOrCustom(const LegalityQuery &Query) const
void aliasActionDefinitions(unsigned OpcodeTo, unsigned OpcodeFrom)
virtual bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI, LostDebugLocObserver &LocObserver) const
Called for instructions with the Custom LegalizationAction.
unsigned getOpcodeIdxForOpcode(unsigned Opcode) const
bool isLegal(const LegalityQuery &Query) const
unsigned getActionDefinitionsIdx(unsigned Opcode) const
virtual bool legalizeIntrinsic(LegalizerHelper &Helper, MachineInstr &MI) const
LegalizeActionStep getAction(const LegalityQuery &Query) const
Determine what action should be taken to legalize the described instruction.
Interface to description of machine instruction set.
Definition MCInstrInfo.h:27
Representation of each machine instruction.
A description of a memory reference used in the backend.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI LegalityPredicate scalarOrEltWiderThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar or a vector with an element type that's wider than the ...
LLVM_ABI LegalityPredicate isScalar(unsigned TypeIdx)
True iff the specified type index is a scalar.
LLVM_ABI LegalityPredicate memSizeInBytesNotPow2(unsigned MMOIdx)
True iff the specified MMO index has a size (rounded to bytes) that is not a power of 2.
LLVM_ABI LegalityPredicate numElementsNotPow2(unsigned TypeIdx)
True iff the specified type index is a vector whose element count is not a power of 2.
LLVM_ABI LegalityPredicate isPointerVector(unsigned TypeIdx)
True iff the specified type index is a vector of pointers (with any address space).
LLVM_ABI LegalityPredicate isPointer(unsigned TypeIdx)
True iff the specified type index is a pointer (with any address space).
LLVM_ABI LegalityPredicate vectorElementCountIsLessThanOrEqualTo(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a vector with a number of elements that's less than or equal to ...
LLVM_ABI LegalityPredicate typeInSet(unsigned TypeIdx, std::initializer_list< LLT > TypesInit)
True iff the given type index is one of the specified types.
LLVM_ABI LegalityPredicate smallerThan(unsigned TypeIdx0, unsigned TypeIdx1)
True iff the first type index has a smaller total bit size than second type index.
LLVM_ABI LegalityPredicate immIs(unsigned ImmIdx, int64_t Imm)
True iff the immediate at the given index has the specified value.
LLVM_ABI LegalityPredicate atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx, AtomicOrdering Ordering)
True iff the specified MMO index has at an atomic ordering of at Ordering or stronger.
LLVM_ABI LegalityPredicate scalarOrEltSizeNotPow2(unsigned TypeIdx)
True iff the specified type index is a scalar or vector whose element size is not a power of 2.
LLVM_ABI LegalityPredicate largerThan(unsigned TypeIdx0, unsigned TypeIdx1)
True iff the first type index has a larger total bit size than second type index.
LLVM_ABI LegalityPredicate typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1, std::initializer_list< std::pair< LLT, LLT > > TypesInit)
True iff the given types for the given pair of type indexes is one of the specified type pairs.
LLVM_ABI LegalityPredicate vectorElementCountIsGreaterThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a vector with a number of elements that's greater than the given...
LLVM_ABI LegalityPredicate memSizeNotByteSizePow2(unsigned MMOIdx)
True iff the specified MMO index has a size that is not an even byte size, or that even byte size is ...
Predicate any(Predicate P0, Predicate P1)
True iff P0 or P1 are true.
LLVM_ABI LegalityPredicate elementTypeIs(unsigned TypeIdx, LLT EltTy)
True if the type index is a vector with element type EltTy.
LLVM_ABI LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1)
True iff the specified type indices are both the same bit size.
LLVM_ABI LegalityPredicate scalarOrEltNarrowerThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar or vector with an element type that's narrower than the...
LLVM_ABI LegalityPredicate immIsNot(unsigned ImmIdx, int64_t Imm)
True iff the immediate at the given index does not have the specified value.
LLVM_ABI LegalityPredicate sizeIs(unsigned TypeIdx, unsigned Size)
True if the total bitwidth of the specified type index is Size bits.
LegalityPredicate typeIsNot(unsigned TypeIdx, LLT Type)
True iff the given type index is not the specified type.
LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
LLVM_ABI LegalityPredicate sizeNotPow2(unsigned TypeIdx)
True iff the specified type index is a scalar whose size is not a power of.
LLVM_ABI LegalityPredicate typeTupleInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned Type2, std::initializer_list< std::tuple< LLT, LLT, LLT > > TypesInit)
True iff the given types for the given tuple of type indexes is one of the specified type tuple.
Predicate all(Predicate P0, Predicate P1)
True iff P0 and P1 are true.
LLVM_ABI LegalityPredicate typePairAndMemDescInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx, std::initializer_list< TypePairAndMemDesc > TypesAndMemDescInit)
True iff the given types for the given pair of type indexes is one of the specified type pairs.
LLVM_ABI LegalityPredicate sizeNotMultipleOf(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar whose size is not a multiple of Size.
LLVM_ABI LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit)
True iff the given type index is the specified type.
Predicate predNot(Predicate P)
True iff P is false.
LLVM_ABI LegalityPredicate scalarWiderThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar that's wider than the given size.
LLVM_ABI LegalityPredicate immInSet(unsigned ImmIdx, std::initializer_list< int64_t > ImmsInit)
True iff the immediate at the given index has one of the specified values.
LLVM_ABI LegalityPredicate scalarNarrowerThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar that's narrower than the given size.
@ FewerElements
The (vector) operation should be implemented by splitting it into sub-vectors where the operation is ...
@ Legal
The operation is expected to be selectable directly by the target, and no transformation is necessary...
@ Libcall
The operation should be implemented as a call to some kind of runtime support library.
@ Unsupported
This operation is completely unsupported on the target.
@ Lower
The operation itself must be expressed in terms of simpler actions on this target.
@ WidenScalar
The operation should be implemented in terms of a wider scalar base-type.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ NarrowScalar
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type.
@ Custom
The target wants to do something special with this combination of operand and type.
@ NotFound
Sentinel value for when no action was found in the specified table.
@ MoreElements
The (vector) operation should be implemented by widening the input vector and ignoring the lanes adde...
LLVM_ABI LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min=0)
Add more elements to the type for the given type index to the next power of.
LLVM_ABI LegalizeMutation changeElementCountTo(unsigned TypeIdx, unsigned FromTypeIdx)
Keep the same scalar or element type as TypeIdx, but take the number of elements from FromTypeIdx.
LLVM_ABI LegalizeMutation scalarize(unsigned TypeIdx)
Break up the vector type for the given type index into the element type.
LLVM_ABI LegalizeMutation changeElementTo(unsigned TypeIdx, unsigned FromTypeIdx)
Keep the same scalar or element type as the given type index.
LLVM_ABI LegalizeMutation widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned Min=0)
Widen the scalar type or vector element type for the given type index to the next power of 2.
LLVM_ABI LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty)
Select this specific type for the given type index.
LLVM_ABI LegalizeMutation widenScalarOrEltToNextMultipleOf(unsigned TypeIdx, unsigned Size)
Widen the scalar type or vector element type for the given type index to next multiple of Size.
LLVM_ABI LegalizeMutation changeElementSizeTo(unsigned TypeIdx, unsigned FromTypeIdx)
Change the scalar size or element size to have the same scalar size as type index FromIndex.
@ OPERAND_LAST_GENERIC
Definition MCInstrDesc.h:73
@ OPERAND_FIRST_GENERIC
Definition MCInstrDesc.h:66
@ OPERAND_FIRST_GENERIC_IMM
Definition MCInstrDesc.h:75
@ OPERAND_LAST_GENERIC_IMM
Definition MCInstrDesc.h:77
This is an optimization pass for GlobalISel generic memory operations.
std::function< std::pair< unsigned, LLT >(const LegalityQuery &)> LegalizeMutation
std::function< bool(const LegalityQuery &)> LegalityPredicate
LLVM_ABI cl::opt< bool > DisableGISelLegalityCheck
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
const MachineInstr * machineFunctionIsIllegal(const MachineFunction &MF)
Checks that MIR is fully legal, returns an illegal instruction if it's not, nullptr otherwise.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Other
Any other memory.
Definition ModRef.h:68
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
bool operator==(const TypePairAndMemDesc &Other) const
bool isCompatible(const TypePairAndMemDesc &Other) const
MemDesc(const MachineMemOperand &MMO)
MemDesc(LLT MemoryTy, uint64_t AlignInBits, AtomicOrdering Ordering, AtomicOrdering FailureOrdering)
The LegalityQuery object bundles together all the information that's needed to decide whether a given...
ArrayRef< int64_t > Immediates
ArrayRef< MemDesc > MMODescrs
Operations which require memory can use this to place requirements on the memory type for each MMO.
constexpr LegalityQuery(unsigned Opcode, ArrayRef< LLT > Types, ArrayRef< MemDesc > MMODescrs={}, ArrayRef< int64_t > Immediates={})
ArrayRef< LLT > Types
LLVM_ABI raw_ostream & print(raw_ostream &OS) const
The result of a query.
LegalizeAction Action
The action to take or the final answer.
LLT NewType
If describing an action, the new type for TypeIdx. Otherwise LLT{}.
unsigned TypeIdx
If describing an action, the type index to change. Otherwise zero.
LegalizeActionStep(LegalizeAction Action, unsigned TypeIdx, const LLT NewType)
bool operator==(const LegalizeActionStep &RHS) const