LLVM 22.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
23#include "llvm/MC/MCInstrDesc.h"
27#include <cassert>
28#include <cstdint>
29#include <tuple>
30#include <utility>
31
32namespace llvm {
33
35
36class MachineFunction;
37class raw_ostream;
38class LegalizerHelper;
40class MachineInstr;
42class MCInstrInfo;
43
44namespace LegalizeActions {
45enum LegalizeAction : std::uint8_t {
46 /// The operation is expected to be selectable directly by the target, and
47 /// no transformation is necessary.
49
50 /// The operation should be synthesized from multiple instructions acting on
51 /// a narrower scalar base-type. For example a 64-bit add might be
52 /// implemented in terms of 32-bit add-with-carry.
54
55 /// The operation should be implemented in terms of a wider scalar
56 /// base-type. For example a <2 x s8> add could be implemented as a <2
57 /// x s32> add (ignoring the high bits).
59
60 /// The (vector) operation should be implemented by splitting it into
61 /// sub-vectors where the operation is legal. For example a <8 x s64> add
62 /// might be implemented as 4 separate <2 x s64> adds. There can be a leftover
63 /// if there are not enough elements for last sub-vector e.g. <7 x s64> add
64 /// will be implemented as 3 separate <2 x s64> adds and one s64 add. Leftover
65 /// types can be avoided by doing MoreElements first.
67
68 /// The (vector) operation should be implemented by widening the input
69 /// vector and ignoring the lanes added by doing so. For example <2 x i8> is
70 /// rarely legal, but you might perform an <8 x i8> and then only look at
71 /// the first two results.
73
74 /// Perform the operation on a different, but equivalently sized type.
76
77 /// The operation itself must be expressed in terms of simpler actions on
78 /// this target. E.g. a SREM replaced by an SDIV and subtraction.
80
81 /// The operation should be implemented as a call to some kind of runtime
82 /// support library. For example this usually happens on machines that don't
83 /// support floating-point operations natively.
85
86 /// The target wants to do something special with this combination of
87 /// operand and type. A callback will be issued when it is needed.
89
90 /// This operation is completely unsupported on the target. A programming
91 /// error has occurred.
93
94 /// Sentinel value for when no action was found in the specified table.
96
97 /// Fall back onto the old rules.
98 /// TODO: Remove this once we've migrated
100};
101} // end namespace LegalizeActions
102LLVM_ABI raw_ostream &operator<<(raw_ostream &OS,
104
106
107/// The LegalityQuery object bundles together all the information that's needed
108/// to decide whether a given operation is legal or not.
109/// For efficiency, it doesn't make a copy of Types so care must be taken not
110/// to free it before using the query.
112 unsigned Opcode;
114
115 struct MemDesc {
118 AtomicOrdering Ordering; //< For cmpxchg this is the success ordering.
119 AtomicOrdering FailureOrdering; //< For cmpxchg, otherwise NotAtomic.
120
121 MemDesc() = default;
127 : MemDesc(MMO.getMemoryType(), MMO.getAlign().value() * 8,
128 MMO.getSuccessOrdering(), MMO.getFailureOrdering()) {}
129 };
130
131 /// Operations which require memory can use this to place requirements on the
132 /// memory type for each MMO.
134
137 : Opcode(Opcode), Types(Types), MMODescrs(MMODescrs) {}
138
139 LLVM_ABI raw_ostream &print(raw_ostream &OS) const;
140};
141
142/// The result of a query. It either indicates a final answer of Legal or
143/// Unsupported or describes an action that must be taken to make an operation
144/// more legal.
146 /// The action to take or the final answer.
148 /// If describing an action, the type index to change. Otherwise zero.
149 unsigned TypeIdx;
150 /// If describing an action, the new type for TypeIdx. Otherwise LLT{}.
152
156
158 : TypeIdx(Step.TypeIdx), NewType(Step.NewType) {
159 switch (Step.Action) {
160 case LegacyLegalizeActions::Legal:
161 Action = LegalizeActions::Legal;
162 break;
163 case LegacyLegalizeActions::NarrowScalar:
164 Action = LegalizeActions::NarrowScalar;
165 break;
166 case LegacyLegalizeActions::WidenScalar:
167 Action = LegalizeActions::WidenScalar;
168 break;
169 case LegacyLegalizeActions::FewerElements:
170 Action = LegalizeActions::FewerElements;
171 break;
172 case LegacyLegalizeActions::MoreElements:
173 Action = LegalizeActions::MoreElements;
174 break;
175 case LegacyLegalizeActions::Bitcast:
176 Action = LegalizeActions::Bitcast;
177 break;
178 case LegacyLegalizeActions::Lower:
179 Action = LegalizeActions::Lower;
180 break;
181 case LegacyLegalizeActions::Libcall:
182 Action = LegalizeActions::Libcall;
183 break;
184 case LegacyLegalizeActions::Custom:
185 Action = LegalizeActions::Custom;
186 break;
187 case LegacyLegalizeActions::Unsupported:
188 Action = LegalizeActions::Unsupported;
189 break;
190 case LegacyLegalizeActions::NotFound:
191 Action = LegalizeActions::NotFound;
192 break;
193 }
194 }
195
196 bool operator==(const LegalizeActionStep &RHS) const {
197 return std::tie(Action, TypeIdx, NewType) ==
198 std::tie(RHS.Action, RHS.TypeIdx, RHS.NewType);
199 }
200};
201
202using LegalityPredicate = std::function<bool (const LegalityQuery &)>;
204 std::function<std::pair<unsigned, LLT>(const LegalityQuery &)>;
205
212
214 return Type0 == Other.Type0 && Type1 == Other.Type1 &&
215 Align == Other.Align && MemTy == Other.MemTy;
216 }
217
218 /// \returns true if this memory access is legal with for the access described
219 /// by \p Other (The alignment is sufficient for the size and result type).
221 return Type0 == Other.Type0 && Type1 == Other.Type1 &&
222 Align >= Other.Align &&
223 // FIXME: This perhaps should be stricter, but the current legality
224 // rules are written only considering the size.
225 MemTy.getSizeInBits() == Other.MemTy.getSizeInBits();
226 }
227};
228
229/// True iff P is false.
230template <typename Predicate> Predicate predNot(Predicate P) {
231 return [=](const LegalityQuery &Query) { return !P(Query); };
232}
233
234/// True iff P0 and P1 are true.
235template<typename Predicate>
237 return [=](const LegalityQuery &Query) {
238 return P0(Query) && P1(Query);
239 };
240}
241/// True iff all given predicates are true.
242template<typename Predicate, typename... Args>
244 return all(all(P0, P1), args...);
245}
246
247/// True iff P0 or P1 are true.
248template<typename Predicate>
250 return [=](const LegalityQuery &Query) {
251 return P0(Query) || P1(Query);
252 };
253}
254/// True iff any given predicates are true.
255template<typename Predicate, typename... Args>
257 return any(any(P0, P1), args...);
258}
259
260/// True iff the given type index is the specified type.
261LLVM_ABI LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit);
262/// True iff the given type index is one of the specified types.
263LLVM_ABI LegalityPredicate typeInSet(unsigned TypeIdx,
264 std::initializer_list<LLT> TypesInit);
265
266/// True iff the given type index is not the specified type.
267inline LegalityPredicate typeIsNot(unsigned TypeIdx, LLT Type) {
268 return [=](const LegalityQuery &Query) {
269 return Query.Types[TypeIdx] != Type;
270 };
271}
272
273/// True iff the given types for the given pair of type indexes is one of the
274/// specified type pairs.
276typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1,
277 std::initializer_list<std::pair<LLT, LLT>> TypesInit);
278/// True iff the given types for the given tuple of type indexes is one of the
279/// specified type tuple.
281typeTupleInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned Type2,
282 std::initializer_list<std::tuple<LLT, LLT, LLT>> TypesInit);
283/// True iff the given types for the given pair of type indexes is one of the
284/// specified type pairs.
286 unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx,
287 std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit);
288/// True iff the specified type index is a scalar.
289LLVM_ABI LegalityPredicate isScalar(unsigned TypeIdx);
290/// True iff the specified type index is a vector.
291LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx);
292/// True iff the specified type index is a pointer (with any address space).
293LLVM_ABI LegalityPredicate isPointer(unsigned TypeIdx);
294/// True iff the specified type index is a pointer with the specified address
295/// space.
296LLVM_ABI LegalityPredicate isPointer(unsigned TypeIdx, unsigned AddrSpace);
297/// True iff the specified type index is a vector of pointers (with any address
298/// space).
300
301/// True if the type index is a vector with element type \p EltTy
302LLVM_ABI LegalityPredicate elementTypeIs(unsigned TypeIdx, LLT EltTy);
303
304/// True iff the specified type index is a scalar that's narrower than the given
305/// size.
306LLVM_ABI LegalityPredicate scalarNarrowerThan(unsigned TypeIdx, unsigned Size);
307
308/// True iff the specified type index is a scalar that's wider than the given
309/// size.
310LLVM_ABI LegalityPredicate scalarWiderThan(unsigned TypeIdx, unsigned Size);
311
312/// True iff the specified type index is a scalar or vector with an element type
313/// that's narrower than the given size.
315 unsigned Size);
316
317/// True iff the specified type index is a scalar or a vector with an element
318/// type that's wider than the given size.
320 unsigned Size);
321
322/// True iff the specified type index is a scalar whose size is not a multiple
323/// of Size.
324LLVM_ABI LegalityPredicate sizeNotMultipleOf(unsigned TypeIdx, unsigned Size);
325
326/// True iff the specified type index is a scalar whose size is not a power of
327/// 2.
328LLVM_ABI LegalityPredicate sizeNotPow2(unsigned TypeIdx);
329
330/// True iff the specified type index is a scalar or vector whose element size
331/// is not a power of 2.
333
334/// True if the total bitwidth of the specified type index is \p Size bits.
335LLVM_ABI LegalityPredicate sizeIs(unsigned TypeIdx, unsigned Size);
336
337/// True iff the specified type indices are both the same bit size.
338LLVM_ABI LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1);
339
340/// True iff the first type index has a larger total bit size than second type
341/// index.
342LLVM_ABI LegalityPredicate largerThan(unsigned TypeIdx0, unsigned TypeIdx1);
343
344/// True iff the first type index has a smaller total bit size than second type
345/// index.
346LLVM_ABI LegalityPredicate smallerThan(unsigned TypeIdx0, unsigned TypeIdx1);
347
348/// True iff the specified MMO index has a size (rounded to bytes) that is not a
349/// power of 2.
351
352/// True iff the specified MMO index has a size that is not an even byte size,
353/// or that even byte size is not a power of 2.
355
356/// True iff the specified type index is a vector whose element count is not a
357/// power of 2.
359/// True iff the specified MMO index has at an atomic ordering of at Ordering or
360/// stronger.
362atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx, AtomicOrdering Ordering);
363} // end namespace LegalityPredicates
364
366/// Select this specific type for the given type index.
367LLVM_ABI LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
368
369/// Keep the same type as the given type index.
370LLVM_ABI LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx);
371
372/// Keep the same scalar or element type as the given type index.
374 unsigned FromTypeIdx);
375
376/// Keep the same scalar or element type as the given type.
377LLVM_ABI LegalizeMutation changeElementTo(unsigned TypeIdx, LLT Ty);
378
379/// Keep the same scalar or element type as \p TypeIdx, but take the number of
380/// elements from \p FromTypeIdx.
382 unsigned FromTypeIdx);
383
384/// Keep the same scalar or element type as \p TypeIdx, but take the number of
385/// elements from \p Ty.
387 ElementCount EC);
388
389/// Change the scalar size or element size to have the same scalar size as type
390/// index \p FromIndex. Unlike changeElementTo, this discards pointer types and
391/// only changes the size.
393 unsigned FromTypeIdx);
394
395/// Widen the scalar type or vector element type for the given type index to the
396/// next power of 2.
398 unsigned Min = 0);
399
400/// Widen the scalar type or vector element type for the given type index to
401/// next multiple of \p Size.
403 unsigned Size);
404
405/// Add more elements to the type for the given type index to the next power of
406/// 2.
408 unsigned Min = 0);
409/// Break up the vector type for the given type index into the element type.
410LLVM_ABI LegalizeMutation scalarize(unsigned TypeIdx);
411} // end namespace LegalizeMutations
412
413/// A single rule in a legalizer info ruleset.
414/// The specified action is chosen when the predicate is true. Where appropriate
415/// for the action (e.g. for WidenScalar) the new type is selected using the
416/// given mutator.
418 LegalityPredicate Predicate;
419 LegalizeAction Action;
420 LegalizeMutation Mutation;
421
422public:
424 LegalizeMutation Mutation = nullptr)
425 : Predicate(Predicate), Action(Action), Mutation(Mutation) {}
426
427 /// Test whether the LegalityQuery matches.
428 bool match(const LegalityQuery &Query) const {
429 return Predicate(Query);
430 }
431
432 LegalizeAction getAction() const { return Action; }
433
434 /// Determine the change to make.
435 std::pair<unsigned, LLT> determineMutation(const LegalityQuery &Query) const {
436 if (Mutation)
437 return Mutation(Query);
438 return std::make_pair(0, LLT{});
439 }
440};
441
443 /// When non-zero, the opcode we are an alias of
444 unsigned AliasOf = 0;
445 /// If true, there is another opcode that aliases this one
446 bool IsAliasedByAnother = false;
448
449#ifndef NDEBUG
450 /// If bit I is set, this rule set contains a rule that may handle (predicate
451 /// or perform an action upon (or both)) the type index I. The uncertainty
452 /// comes from free-form rules executing user-provided lambda functions. We
453 /// conservatively assume such rules do the right thing and cover all type
454 /// indices. The bitset is intentionally 1 bit wider than it absolutely needs
455 /// to be to distinguish such cases from the cases where all type indices are
456 /// individually handled.
461#endif
462
463 unsigned typeIdx(unsigned TypeIdx) {
464 assert(TypeIdx <=
466 "Type Index is out of bounds");
467#ifndef NDEBUG
468 TypeIdxsCovered.set(TypeIdx);
469#endif
470 return TypeIdx;
471 }
472
473 void markAllIdxsAsCovered() {
474#ifndef NDEBUG
475 TypeIdxsCovered.set();
476 ImmIdxsCovered.set();
477#endif
478 }
479
480 void add(const LegalizeRule &Rule) {
481 assert(AliasOf == 0 &&
482 "RuleSet is aliased, change the representative opcode instead");
483 Rules.push_back(Rule);
484 }
485
486 static bool always(const LegalityQuery &) { return true; }
487
488 /// Use the given action when the predicate is true.
489 /// Action should not be an action that requires mutation.
490 LegalizeRuleSet &actionIf(LegalizeAction Action,
492 add({Predicate, Action});
493 return *this;
494 }
495 /// Use the given action when the predicate is true.
496 /// Action should be an action that requires mutation.
499 add({Predicate, Action, Mutation});
500 return *this;
501 }
502 /// Use the given action when type index 0 is any type in the given list.
503 /// Action should not be an action that requires mutation.
504 LegalizeRuleSet &actionFor(LegalizeAction Action,
505 std::initializer_list<LLT> Types) {
506 using namespace LegalityPredicates;
507 return actionIf(Action, typeInSet(typeIdx(0), Types));
508 }
509 /// Use the given action when type index 0 is any type in the given list.
510 /// Action should be an action that requires mutation.
511 LegalizeRuleSet &actionFor(LegalizeAction Action,
512 std::initializer_list<LLT> Types,
514 using namespace LegalityPredicates;
515 return actionIf(Action, typeInSet(typeIdx(0), Types), Mutation);
516 }
517 /// Use the given action when type indexes 0 and 1 is any type pair in the
518 /// given list.
519 /// Action should not be an action that requires mutation.
520 LegalizeRuleSet &actionFor(LegalizeAction Action,
521 std::initializer_list<std::pair<LLT, LLT>> Types) {
522 using namespace LegalityPredicates;
523 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
524 }
525
527 actionFor(LegalizeAction Action,
528 std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
529 using namespace LegalityPredicates;
530 return actionIf(Action,
531 typeTupleInSet(typeIdx(0), typeIdx(1), typeIdx(2), Types));
532 }
533
534 /// Use the given action when type indexes 0 and 1 is any type pair in the
535 /// given list.
536 /// Action should be an action that requires mutation.
537 LegalizeRuleSet &actionFor(LegalizeAction Action,
538 std::initializer_list<std::pair<LLT, LLT>> Types,
540 using namespace LegalityPredicates;
541 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types),
542 Mutation);
543 }
544 /// Use the given action when type index 0 is any type in the given list and
545 /// imm index 0 is anything. Action should not be an action that requires
546 /// mutation.
547 LegalizeRuleSet &actionForTypeWithAnyImm(LegalizeAction Action,
548 std::initializer_list<LLT> Types) {
549 using namespace LegalityPredicates;
550 immIdx(0); // Inform verifier imm idx 0 is handled.
551 return actionIf(Action, typeInSet(typeIdx(0), Types));
552 }
553
554 LegalizeRuleSet &actionForTypeWithAnyImm(
555 LegalizeAction Action, std::initializer_list<std::pair<LLT, LLT>> Types) {
556 using namespace LegalityPredicates;
557 immIdx(0); // Inform verifier imm idx 0 is handled.
558 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
559 }
560
561 /// Use the given action when type indexes 0 and 1 are both in the given list.
562 /// That is, the type pair is in the cartesian product of the list.
563 /// Action should not be an action that requires mutation.
564 LegalizeRuleSet &actionForCartesianProduct(LegalizeAction Action,
565 std::initializer_list<LLT> Types) {
566 using namespace LegalityPredicates;
567 return actionIf(Action, all(typeInSet(typeIdx(0), Types),
568 typeInSet(typeIdx(1), Types)));
569 }
570 /// Use the given action when type indexes 0 and 1 are both in their
571 /// respective lists.
572 /// That is, the type pair is in the cartesian product of the lists
573 /// Action should not be an action that requires mutation.
575 actionForCartesianProduct(LegalizeAction Action,
576 std::initializer_list<LLT> Types0,
577 std::initializer_list<LLT> Types1) {
578 using namespace LegalityPredicates;
579 return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
580 typeInSet(typeIdx(1), Types1)));
581 }
582 /// Use the given action when type indexes 0, 1, and 2 are all in their
583 /// respective lists.
584 /// That is, the type triple is in the cartesian product of the lists
585 /// Action should not be an action that requires mutation.
586 LegalizeRuleSet &actionForCartesianProduct(
587 LegalizeAction Action, std::initializer_list<LLT> Types0,
588 std::initializer_list<LLT> Types1, std::initializer_list<LLT> Types2) {
589 using namespace LegalityPredicates;
590 return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
591 all(typeInSet(typeIdx(1), Types1),
592 typeInSet(typeIdx(2), Types2))));
593 }
594
595public:
596 LegalizeRuleSet() = default;
597
598 bool isAliasedByAnother() { return IsAliasedByAnother; }
599 void setIsAliasedByAnother() { IsAliasedByAnother = true; }
600 void aliasTo(unsigned Opcode) {
601 assert((AliasOf == 0 || AliasOf == Opcode) &&
602 "Opcode is already aliased to another opcode");
603 assert(Rules.empty() && "Aliasing will discard rules");
604 AliasOf = Opcode;
605 }
606 unsigned getAlias() const { return AliasOf; }
607
608 unsigned immIdx(unsigned ImmIdx) {
611 "Imm Index is out of bounds");
612#ifndef NDEBUG
613 ImmIdxsCovered.set(ImmIdx);
614#endif
615 return ImmIdx;
616 }
617
618 /// The instruction is legal if predicate is true.
620 // We have no choice but conservatively assume that the free-form
621 // user-provided Predicate properly handles all type indices:
622 markAllIdxsAsCovered();
623 return actionIf(LegalizeAction::Legal, Predicate);
624 }
625 /// The instruction is legal when type index 0 is any type in the given list.
626 LegalizeRuleSet &legalFor(std::initializer_list<LLT> Types) {
627 return actionFor(LegalizeAction::Legal, Types);
628 }
629 LegalizeRuleSet &legalFor(bool Pred, std::initializer_list<LLT> Types) {
630 if (!Pred)
631 return *this;
632 return actionFor(LegalizeAction::Legal, Types);
633 }
634 /// The instruction is legal when type indexes 0 and 1 is any type pair in the
635 /// given list.
636 LegalizeRuleSet &legalFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
637 return actionFor(LegalizeAction::Legal, Types);
638 }
640 std::initializer_list<std::pair<LLT, LLT>> Types) {
641 if (!Pred)
642 return *this;
643 return actionFor(LegalizeAction::Legal, Types);
644 }
646 legalFor(bool Pred, std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
647 if (!Pred)
648 return *this;
649 return actionFor(LegalizeAction::Legal, Types);
650 }
651 /// The instruction is legal when type index 0 is any type in the given list
652 /// and imm index 0 is anything.
653 LegalizeRuleSet &legalForTypeWithAnyImm(std::initializer_list<LLT> Types) {
654 markAllIdxsAsCovered();
655 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
656 }
657
659 std::initializer_list<std::pair<LLT, LLT>> Types) {
660 markAllIdxsAsCovered();
661 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
662 }
663
664 /// The instruction is legal when type indexes 0 and 1 along with the memory
665 /// size and minimum alignment is any type and size tuple in the given list.
667 std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
668 TypesAndMemDesc) {
669 return actionIf(LegalizeAction::Legal,
671 typeIdx(0), typeIdx(1), /*MMOIdx*/ 0, TypesAndMemDesc));
672 }
673 /// The instruction is legal when type indexes 0 and 1 are both in the given
674 /// list. That is, the type pair is in the cartesian product of the list.
675 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types) {
676 return actionForCartesianProduct(LegalizeAction::Legal, Types);
677 }
678 /// The instruction is legal when type indexes 0 and 1 are both their
679 /// respective lists.
680 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
681 std::initializer_list<LLT> Types1) {
682 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
683 }
684 /// The instruction is legal when type indexes 0, 1, and 2 are both their
685 /// respective lists.
686 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
687 std::initializer_list<LLT> Types1,
688 std::initializer_list<LLT> Types2) {
689 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1,
690 Types2);
691 }
692
694 using namespace LegalizeMutations;
695 markAllIdxsAsCovered();
696 return actionIf(LegalizeAction::Legal, always);
697 }
698
699 /// The specified type index is coerced if predicate is true.
702 // We have no choice but conservatively assume that lowering with a
703 // free-form user provided Predicate properly handles all type indices:
704 markAllIdxsAsCovered();
705 return actionIf(LegalizeAction::Bitcast, Predicate, Mutation);
706 }
707
708 /// The instruction is lowered.
710 using namespace LegalizeMutations;
711 // We have no choice but conservatively assume that predicate-less lowering
712 // properly handles all type indices by design:
713 markAllIdxsAsCovered();
714 return actionIf(LegalizeAction::Lower, always);
715 }
716 /// The instruction is lowered if predicate is true. Keep type index 0 as the
717 /// same type.
719 using namespace LegalizeMutations;
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);
724 }
725 /// The instruction is lowered if predicate is true.
728 // We have no choice but conservatively assume that lowering with a
729 // free-form user provided Predicate properly handles all type indices:
730 markAllIdxsAsCovered();
731 return actionIf(LegalizeAction::Lower, Predicate, Mutation);
732 }
733 /// The instruction is lowered when type index 0 is any type in the given
734 /// list. Keep type index 0 as the same type.
735 LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types) {
736 return actionFor(LegalizeAction::Lower, Types);
737 }
738 /// The instruction is lowered when type index 0 is any type in the given
739 /// list.
740 LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types,
742 return actionFor(LegalizeAction::Lower, Types, Mutation);
743 }
744 /// The instruction is lowered when type indexes 0 and 1 is any type pair in
745 /// the given list. Keep type index 0 as the same type.
746 LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
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 /// Narrow the scalar to the one selected by the mutation if the predicate is
826 /// true.
829 // We have no choice but conservatively assume that an action with a
830 // free-form user provided Predicate properly handles all type indices:
831 markAllIdxsAsCovered();
832 return actionIf(LegalizeAction::NarrowScalar, Predicate, Mutation);
833 }
834 /// Narrow the scalar, specified in mutation, when type indexes 0 and 1 is any
835 /// type pair in the given list.
837 narrowScalarFor(std::initializer_list<std::pair<LLT, LLT>> Types,
839 return actionFor(LegalizeAction::NarrowScalar, Types, Mutation);
840 }
841
842 /// Add more elements to reach the type selected by the mutation if the
843 /// predicate is true.
846 // We have no choice but conservatively assume that an action with a
847 // free-form user provided Predicate properly handles all type indices:
848 markAllIdxsAsCovered();
849 return actionIf(LegalizeAction::MoreElements, Predicate, Mutation);
850 }
851 /// Remove elements to reach the type selected by the mutation if the
852 /// predicate is true.
855 // We have no choice but conservatively assume that an action with a
856 // free-form user provided Predicate properly handles all type indices:
857 markAllIdxsAsCovered();
858 return actionIf(LegalizeAction::FewerElements, Predicate, Mutation);
859 }
860
861 /// The instruction is unsupported.
863 markAllIdxsAsCovered();
864 return actionIf(LegalizeAction::Unsupported, always);
865 }
867 return actionIf(LegalizeAction::Unsupported, Predicate);
868 }
869
870 LegalizeRuleSet &unsupportedFor(std::initializer_list<LLT> Types) {
871 return actionFor(LegalizeAction::Unsupported, Types);
872 }
873
875 return actionIf(LegalizeAction::Unsupported,
877 }
878
879 /// Lower a memory operation if the memory size, rounded to bytes, is not a
880 /// power of 2. For example, this will not trigger for s1 or s7, but will for
881 /// s24.
883 return actionIf(LegalizeAction::Lower,
885 }
886
887 /// Lower a memory operation if the memory access size is not a round power of
888 /// 2 byte size. This is stricter than lowerIfMemSizeNotPow2, and more likely
889 /// what you want (e.g. this will lower s1, s7 and s24).
891 return actionIf(LegalizeAction::Lower,
893 }
894
896 // We have no choice but conservatively assume that a custom action with a
897 // free-form user provided Predicate properly handles all type indices:
898 markAllIdxsAsCovered();
899 return actionIf(LegalizeAction::Custom, Predicate);
900 }
901 LegalizeRuleSet &customFor(std::initializer_list<LLT> Types) {
902 return actionFor(LegalizeAction::Custom, Types);
903 }
904 LegalizeRuleSet &customFor(bool Pred, std::initializer_list<LLT> Types) {
905 if (!Pred)
906 return *this;
907 return actionFor(LegalizeAction::Custom, Types);
908 }
909
910 /// The instruction is custom when type indexes 0 and 1 is any type pair in
911 /// the given list.
912 LegalizeRuleSet &customFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
913 return actionFor(LegalizeAction::Custom, Types);
914 }
916 std::initializer_list<std::pair<LLT, LLT>> Types) {
917 if (!Pred)
918 return *this;
919 return actionFor(LegalizeAction::Custom, Types);
920 }
921
922 LegalizeRuleSet &customForCartesianProduct(std::initializer_list<LLT> Types) {
923 return actionForCartesianProduct(LegalizeAction::Custom, Types);
924 }
925 /// The instruction is custom when type indexes 0 and 1 are both in their
926 /// respective lists.
928 customForCartesianProduct(std::initializer_list<LLT> Types0,
929 std::initializer_list<LLT> Types1) {
930 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
931 }
932 /// The instruction is custom when type indexes 0, 1, and 2 are all in
933 /// their respective lists.
935 customForCartesianProduct(std::initializer_list<LLT> Types0,
936 std::initializer_list<LLT> Types1,
937 std::initializer_list<LLT> Types2) {
938 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1,
939 Types2);
940 }
941
942 /// The instruction is custom when the predicate is true and type indexes 0
943 /// and 1 are all in their respective lists.
945 customForCartesianProduct(bool Pred, std::initializer_list<LLT> Types0,
946 std::initializer_list<LLT> Types1) {
947 if (!Pred)
948 return *this;
949 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
950 }
951
952 /// Unconditionally custom lower.
954 return customIf(always);
955 }
956
957 /// Widen the scalar to the next power of two that is at least MinSize.
958 /// No effect if the type is a power of two, except if the type is smaller
959 /// than MinSize, or if the type is a vector type.
961 unsigned MinSize = 0) {
962 using namespace LegalityPredicates;
963 return actionIf(
964 LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
966 }
967
968 /// Widen the scalar to the next multiple of Size. No effect if the
969 /// type is not a scalar or is a multiple of Size.
971 unsigned Size) {
972 using namespace LegalityPredicates;
973 return actionIf(
974 LegalizeAction::WidenScalar, sizeNotMultipleOf(typeIdx(TypeIdx), Size),
976 }
977
978 /// Widen the scalar or vector element type to the next power of two that is
979 /// at least MinSize. No effect if the scalar size is a power of two.
981 unsigned MinSize = 0) {
982 using namespace LegalityPredicates;
983 return actionIf(
984 LegalizeAction::WidenScalar, scalarOrEltSizeNotPow2(typeIdx(TypeIdx)),
986 }
987
988 /// Widen the scalar or vector element type to the next power of two that is
989 /// at least MinSize. No effect if the scalar size is a power of two.
991 unsigned MinSize = 0) {
992 using namespace LegalityPredicates;
993 return actionIf(
994 LegalizeAction::WidenScalar,
995 any(scalarOrEltNarrowerThan(TypeIdx, MinSize),
996 scalarOrEltSizeNotPow2(typeIdx(TypeIdx))),
998 }
999
1001 using namespace LegalityPredicates;
1002 return actionIf(LegalizeAction::NarrowScalar, isScalar(typeIdx(TypeIdx)),
1003 Mutation);
1004 }
1005
1006 LegalizeRuleSet &scalarize(unsigned TypeIdx) {
1007 using namespace LegalityPredicates;
1008 return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)),
1010 }
1011
1013 using namespace LegalityPredicates;
1014 return actionIf(LegalizeAction::FewerElements,
1015 all(Predicate, isVector(typeIdx(TypeIdx))),
1017 }
1018
1019 /// Ensure the scalar or element is at least as wide as Ty.
1020 LegalizeRuleSet &minScalarOrElt(unsigned TypeIdx, const LLT Ty) {
1021 using namespace LegalityPredicates;
1022 using namespace LegalizeMutations;
1023 return actionIf(LegalizeAction::WidenScalar,
1024 scalarOrEltNarrowerThan(TypeIdx, Ty.getScalarSizeInBits()),
1025 changeElementTo(typeIdx(TypeIdx), Ty));
1026 }
1027
1028 /// Ensure the scalar or element is at least as wide as Ty.
1030 unsigned TypeIdx, const LLT Ty) {
1031 using namespace LegalityPredicates;
1032 using namespace LegalizeMutations;
1033 return actionIf(LegalizeAction::WidenScalar,
1034 all(Predicate, scalarOrEltNarrowerThan(
1035 TypeIdx, Ty.getScalarSizeInBits())),
1036 changeElementTo(typeIdx(TypeIdx), Ty));
1037 }
1038
1039 /// Ensure the vector size is at least as wide as VectorSize by promoting the
1040 /// element.
1042 unsigned VectorSize) {
1043 using namespace LegalityPredicates;
1044 using namespace LegalizeMutations;
1045 return actionIf(
1046 LegalizeAction::WidenScalar,
1047 [=](const LegalityQuery &Query) {
1048 const LLT VecTy = Query.Types[TypeIdx];
1049 return VecTy.isFixedVector() && VecTy.getSizeInBits() < VectorSize;
1050 },
1051 [=](const LegalityQuery &Query) {
1052 const LLT VecTy = Query.Types[TypeIdx];
1053 unsigned NumElts = VecTy.getNumElements();
1054 unsigned MinSize = VectorSize / NumElts;
1055 LLT NewTy = LLT::fixed_vector(NumElts, LLT::scalar(MinSize));
1056 return std::make_pair(TypeIdx, NewTy);
1057 });
1058 }
1059
1060 /// Ensure the scalar is at least as wide as Ty.
1061 LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT Ty) {
1062 using namespace LegalityPredicates;
1063 using namespace LegalizeMutations;
1064 return actionIf(LegalizeAction::WidenScalar,
1065 scalarNarrowerThan(TypeIdx, Ty.getSizeInBits()),
1066 changeTo(typeIdx(TypeIdx), Ty));
1067 }
1068 LegalizeRuleSet &minScalar(bool Pred, unsigned TypeIdx, const LLT Ty) {
1069 if (!Pred)
1070 return *this;
1071 return minScalar(TypeIdx, Ty);
1072 }
1073
1074 /// Ensure the scalar is at least as wide as Ty if condition is met.
1076 const LLT Ty) {
1077 using namespace LegalityPredicates;
1078 using namespace LegalizeMutations;
1079 return actionIf(
1080 LegalizeAction::WidenScalar,
1081 [=](const LegalityQuery &Query) {
1082 const LLT QueryTy = Query.Types[TypeIdx];
1083 return QueryTy.isScalar() &&
1084 QueryTy.getSizeInBits() < Ty.getSizeInBits() &&
1085 Predicate(Query);
1086 },
1087 changeTo(typeIdx(TypeIdx), Ty));
1088 }
1089
1090 /// Ensure the scalar is at most as wide as Ty.
1091 LegalizeRuleSet &maxScalarOrElt(unsigned TypeIdx, const LLT Ty) {
1092 using namespace LegalityPredicates;
1093 using namespace LegalizeMutations;
1094 return actionIf(LegalizeAction::NarrowScalar,
1095 scalarOrEltWiderThan(TypeIdx, Ty.getScalarSizeInBits()),
1096 changeElementTo(typeIdx(TypeIdx), Ty));
1097 }
1098
1099 /// Ensure the scalar is at most as wide as Ty.
1100 LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT Ty) {
1101 using namespace LegalityPredicates;
1102 using namespace LegalizeMutations;
1103 return actionIf(LegalizeAction::NarrowScalar,
1104 scalarWiderThan(TypeIdx, Ty.getSizeInBits()),
1105 changeTo(typeIdx(TypeIdx), Ty));
1106 }
1107
1108 /// Conditionally limit the maximum size of the scalar.
1109 /// For example, when the maximum size of one type depends on the size of
1110 /// another such as extracting N bits from an M bit container.
1112 const LLT Ty) {
1113 using namespace LegalityPredicates;
1114 using namespace LegalizeMutations;
1115 return actionIf(
1116 LegalizeAction::NarrowScalar,
1117 [=](const LegalityQuery &Query) {
1118 const LLT QueryTy = Query.Types[TypeIdx];
1119 return QueryTy.isScalar() &&
1120 QueryTy.getSizeInBits() > Ty.getSizeInBits() &&
1121 Predicate(Query);
1122 },
1123 changeElementTo(typeIdx(TypeIdx), Ty));
1124 }
1125
1126 /// Limit the range of scalar sizes to MinTy and MaxTy.
1127 LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT MinTy,
1128 const LLT MaxTy) {
1129 assert(MinTy.isScalar() && MaxTy.isScalar() && "Expected scalar types");
1130 return minScalar(TypeIdx, MinTy).maxScalar(TypeIdx, MaxTy);
1131 }
1132
1133 LegalizeRuleSet &clampScalar(bool Pred, unsigned TypeIdx, const LLT MinTy,
1134 const LLT MaxTy) {
1135 if (!Pred)
1136 return *this;
1137 return clampScalar(TypeIdx, MinTy, MaxTy);
1138 }
1139
1140 /// Limit the range of scalar sizes to MinTy and MaxTy.
1141 LegalizeRuleSet &clampScalarOrElt(unsigned TypeIdx, const LLT MinTy,
1142 const LLT MaxTy) {
1143 return minScalarOrElt(TypeIdx, MinTy).maxScalarOrElt(TypeIdx, MaxTy);
1144 }
1145
1146 /// Widen the scalar to match the size of another.
1147 LegalizeRuleSet &minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx) {
1148 typeIdx(TypeIdx);
1149 return actionIf(
1150 LegalizeAction::WidenScalar,
1151 [=](const LegalityQuery &Query) {
1152 return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
1153 Query.Types[TypeIdx].getSizeInBits();
1154 },
1155 LegalizeMutations::changeElementSizeTo(TypeIdx, LargeTypeIdx));
1156 }
1157
1158 /// Narrow the scalar to match the size of another.
1159 LegalizeRuleSet &maxScalarSameAs(unsigned TypeIdx, unsigned NarrowTypeIdx) {
1160 typeIdx(TypeIdx);
1161 return actionIf(
1162 LegalizeAction::NarrowScalar,
1163 [=](const LegalityQuery &Query) {
1164 return Query.Types[NarrowTypeIdx].getScalarSizeInBits() <
1165 Query.Types[TypeIdx].getSizeInBits();
1166 },
1167 LegalizeMutations::changeElementSizeTo(TypeIdx, NarrowTypeIdx));
1168 }
1169
1170 /// Change the type \p TypeIdx to have the same scalar size as type \p
1171 /// SameSizeIdx.
1172 LegalizeRuleSet &scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx) {
1173 return minScalarSameAs(TypeIdx, SameSizeIdx)
1174 .maxScalarSameAs(TypeIdx, SameSizeIdx);
1175 }
1176
1177 /// Conditionally widen the scalar or elt to match the size of another.
1179 unsigned TypeIdx, unsigned LargeTypeIdx) {
1180 typeIdx(TypeIdx);
1181 return widenScalarIf(
1182 [=](const LegalityQuery &Query) {
1183 return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
1184 Query.Types[TypeIdx].getScalarSizeInBits() &&
1185 Predicate(Query);
1186 },
1187 [=](const LegalityQuery &Query) {
1188 LLT T = Query.Types[LargeTypeIdx];
1189 if (T.isPointerVector())
1190 T = T.changeElementType(LLT::scalar(T.getScalarSizeInBits()));
1191 return std::make_pair(TypeIdx, T);
1192 });
1193 }
1194
1195 /// Conditionally narrow the scalar or elt to match the size of another.
1197 unsigned TypeIdx,
1198 unsigned SmallTypeIdx) {
1199 typeIdx(TypeIdx);
1200 return narrowScalarIf(
1201 [=](const LegalityQuery &Query) {
1202 return Query.Types[SmallTypeIdx].getScalarSizeInBits() <
1203 Query.Types[TypeIdx].getScalarSizeInBits() &&
1204 Predicate(Query);
1205 },
1206 [=](const LegalityQuery &Query) {
1207 LLT T = Query.Types[SmallTypeIdx];
1208 return std::make_pair(TypeIdx, T);
1209 });
1210 }
1211
1212 /// Add more elements to the vector to reach the next power of two.
1213 /// No effect if the type is not a vector or the element count is a power of
1214 /// two.
1216 using namespace LegalityPredicates;
1217 return actionIf(LegalizeAction::MoreElements,
1218 numElementsNotPow2(typeIdx(TypeIdx)),
1220 }
1221
1222 /// Limit the number of elements in EltTy vectors to at least MinElements.
1223 LegalizeRuleSet &clampMinNumElements(unsigned TypeIdx, const LLT EltTy,
1224 unsigned MinElements) {
1225 // Mark the type index as covered:
1226 typeIdx(TypeIdx);
1227 return actionIf(
1228 LegalizeAction::MoreElements,
1229 [=](const LegalityQuery &Query) {
1230 LLT VecTy = Query.Types[TypeIdx];
1231 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1232 VecTy.getNumElements() < MinElements;
1233 },
1234 [=](const LegalityQuery &Query) {
1235 LLT VecTy = Query.Types[TypeIdx];
1236 return std::make_pair(
1237 TypeIdx, LLT::fixed_vector(MinElements, VecTy.getElementType()));
1238 });
1239 }
1240
1241 /// Set number of elements to nearest larger multiple of NumElts.
1242 LegalizeRuleSet &alignNumElementsTo(unsigned TypeIdx, const LLT EltTy,
1243 unsigned NumElts) {
1244 typeIdx(TypeIdx);
1245 return actionIf(
1246 LegalizeAction::MoreElements,
1247 [=](const LegalityQuery &Query) {
1248 LLT VecTy = Query.Types[TypeIdx];
1249 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1250 (VecTy.getNumElements() % NumElts != 0);
1251 },
1252 [=](const LegalityQuery &Query) {
1253 LLT VecTy = Query.Types[TypeIdx];
1254 unsigned NewSize = alignTo(VecTy.getNumElements(), NumElts);
1255 return std::make_pair(
1256 TypeIdx, LLT::fixed_vector(NewSize, VecTy.getElementType()));
1257 });
1258 }
1259
1260 /// Limit the number of elements in EltTy vectors to at most MaxElements.
1261 LegalizeRuleSet &clampMaxNumElements(unsigned TypeIdx, const LLT EltTy,
1262 unsigned MaxElements) {
1263 // Mark the type index as covered:
1264 typeIdx(TypeIdx);
1265 return actionIf(
1266 LegalizeAction::FewerElements,
1267 [=](const LegalityQuery &Query) {
1268 LLT VecTy = Query.Types[TypeIdx];
1269 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1270 VecTy.getNumElements() > MaxElements;
1271 },
1272 [=](const LegalityQuery &Query) {
1273 LLT VecTy = Query.Types[TypeIdx];
1274 LLT NewTy = LLT::scalarOrVector(ElementCount::getFixed(MaxElements),
1275 VecTy.getElementType());
1276 return std::make_pair(TypeIdx, NewTy);
1277 });
1278 }
1279 /// Limit the number of elements for the given vectors to at least MinTy's
1280 /// number of elements and at most MaxTy's number of elements.
1281 ///
1282 /// No effect if the type is not a vector or does not have the same element
1283 /// type as the constraints.
1284 /// The element type of MinTy and MaxTy must match.
1285 LegalizeRuleSet &clampNumElements(unsigned TypeIdx, const LLT MinTy,
1286 const LLT MaxTy) {
1287 assert(MinTy.getElementType() == MaxTy.getElementType() &&
1288 "Expected element types to agree");
1289
1290 assert((!MinTy.isScalableVector() && !MaxTy.isScalableVector()) &&
1291 "Unexpected scalable vectors");
1292
1293 const LLT EltTy = MinTy.getElementType();
1294 return clampMinNumElements(TypeIdx, EltTy, MinTy.getNumElements())
1295 .clampMaxNumElements(TypeIdx, EltTy, MaxTy.getNumElements());
1296 }
1297
1298 /// Express \p EltTy vectors strictly using vectors with \p NumElts elements
1299 /// (or scalars when \p NumElts equals 1).
1300 /// First pad with undef elements to nearest larger multiple of \p NumElts.
1301 /// Then perform split with all sub-instructions having the same type.
1302 /// Using clampMaxNumElements (non-strict) can result in leftover instruction
1303 /// with different type (fewer elements then \p NumElts or scalar).
1304 /// No effect if the type is not a vector.
1305 LegalizeRuleSet &clampMaxNumElementsStrict(unsigned TypeIdx, const LLT EltTy,
1306 unsigned NumElts) {
1307 return alignNumElementsTo(TypeIdx, EltTy, NumElts)
1308 .clampMaxNumElements(TypeIdx, EltTy, NumElts);
1309 }
1310
1311 /// Fallback on the previous implementation. This should only be used while
1312 /// porting a rule.
1314 add({always, LegalizeAction::UseLegacyRules});
1315 return *this;
1316 }
1317
1318 /// Check if there is no type index which is obviously not handled by the
1319 /// LegalizeRuleSet in any way at all.
1320 /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
1321 LLVM_ABI bool verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const;
1322 /// Check if there is no imm index which is obviously not handled by the
1323 /// LegalizeRuleSet in any way at all.
1324 /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
1325 LLVM_ABI bool verifyImmIdxsCoverage(unsigned NumImmIdxs) const;
1326
1327 /// Apply the ruleset to the given LegalityQuery.
1328 LLVM_ABI LegalizeActionStep apply(const LegalityQuery &Query) const;
1329};
1330
1332public:
1333 virtual ~LegalizerInfo() = default;
1334
1336 return LegacyInfo;
1337 }
1339
1340 unsigned getOpcodeIdxForOpcode(unsigned Opcode) const;
1341 unsigned getActionDefinitionsIdx(unsigned Opcode) const;
1342
1343 /// Perform simple self-diagnostic and assert if there is anything obviously
1344 /// wrong with the actions set up.
1345 void verify(const MCInstrInfo &MII) const;
1346
1347 /// Get the action definitions for the given opcode. Use this to run a
1348 /// LegalityQuery through the definitions.
1349 const LegalizeRuleSet &getActionDefinitions(unsigned Opcode) const;
1350
1351 /// Get the action definition builder for the given opcode. Use this to define
1352 /// the action definitions.
1353 ///
1354 /// It is an error to request an opcode that has already been requested by the
1355 /// multiple-opcode variant.
1356 LegalizeRuleSet &getActionDefinitionsBuilder(unsigned Opcode);
1357
1358 /// Get the action definition builder for the given set of opcodes. Use this
1359 /// to define the action definitions for multiple opcodes at once. The first
1360 /// opcode given will be considered the representative opcode and will hold
1361 /// the definitions whereas the other opcodes will be configured to refer to
1362 /// the representative opcode. This lowers memory requirements and very
1363 /// slightly improves performance.
1364 ///
1365 /// It would be very easy to introduce unexpected side-effects as a result of
1366 /// this aliasing if it were permitted to request different but intersecting
1367 /// sets of opcodes but that is difficult to keep track of. It is therefore an
1368 /// error to request the same opcode twice using this API, to request an
1369 /// opcode that already has definitions, or to use the single-opcode API on an
1370 /// opcode that has already been requested by this API.
1372 getActionDefinitionsBuilder(std::initializer_list<unsigned> Opcodes);
1373 void aliasActionDefinitions(unsigned OpcodeTo, unsigned OpcodeFrom);
1374
1375 /// Determine what action should be taken to legalize the described
1376 /// instruction. Requires computeTables to have been called.
1377 ///
1378 /// \returns a description of the next legalization step to perform.
1379 LegalizeActionStep getAction(const LegalityQuery &Query) const;
1380
1381 /// Determine what action should be taken to legalize the given generic
1382 /// instruction.
1383 ///
1384 /// \returns a description of the next legalization step to perform.
1385 LegalizeActionStep getAction(const MachineInstr &MI,
1386 const MachineRegisterInfo &MRI) const;
1387
1388 bool isLegal(const LegalityQuery &Query) const {
1389 return getAction(Query).Action == LegalizeAction::Legal;
1390 }
1391
1392 bool isLegalOrCustom(const LegalityQuery &Query) const {
1393 auto Action = getAction(Query).Action;
1394 return Action == LegalizeAction::Legal || Action == LegalizeAction::Custom;
1395 }
1396
1397 bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
1398 bool isLegalOrCustom(const MachineInstr &MI,
1399 const MachineRegisterInfo &MRI) const;
1400
1401 /// Called for instructions with the Custom LegalizationAction.
1403 LostDebugLocObserver &LocObserver) const {
1404 llvm_unreachable("must implement this if custom action is used");
1405 }
1406
1407 /// \returns true if MI is either legal or has been legalized and false if not
1408 /// legal.
1409 /// Return true if MI is either legal or has been legalized and false
1410 /// if not legal.
1412 MachineInstr &MI) const {
1413 return true;
1414 }
1415
1416 /// Return the opcode (SEXT/ZEXT/ANYEXT) that should be performed while
1417 /// widening a constant of type SmallTy which targets can override.
1418 /// For eg, the DAG does (SmallTy.isByteSized() ? G_SEXT : G_ZEXT) which
1419 /// will be the default.
1420 virtual unsigned getExtOpcodeForWideningConstant(LLT SmallTy) const;
1421
1422private:
1423 static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
1424 static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
1425
1426 LegalizeRuleSet RulesForOpcode[LastOp - FirstOp + 1];
1427 LegacyLegalizerInfo LegacyInfo;
1428};
1429
1430#ifndef NDEBUG
1431/// Checks that MIR is fully legal, returns an illegal instruction if it's not,
1432/// nullptr otherwise
1433const MachineInstr *machineFunctionIsIllegal(const MachineFunction &MF);
1434#endif
1435
1436} // end namespace llvm.
1437
1438#endif // LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Atomic ordering constants.
#define LLVM_ABI
Definition Compiler.h:213
IRTranslator LLVM IR MI
Interface for Targets to specify which operations they can successfully select and how the others sho...
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
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:310
constexpr bool isScalableVector() const
Returns true if the LLT is a scalable vector.
constexpr bool isScalar() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
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.
constexpr LLT getElementType() const
Returns the vector's element type. Only valid for vector 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.
static constexpr LLT scalarOrVector(ElementCount EC, LLT ScalarTy)
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 & 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 & 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 & 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 & fallback()
Fallback on the previous implementation.
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 & 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
virtual ~LegalizerInfo()=default
const LegacyLegalizerInfo & getLegacyLegalizerInfo() const
LegacyLegalizerInfo & getLegacyLegalizerInfo()
bool isLegalOrCustom(const LegalityQuery &Query) const
virtual bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI, LostDebugLocObserver &LocObserver) const
Called for instructions with the Custom LegalizationAction.
bool isLegal(const LegalityQuery &Query) 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:45
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 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 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 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 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 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.
@ UseLegacyRules
Fall back onto the old rules.
@ 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:74
@ OPERAND_FIRST_GENERIC
Definition MCInstrDesc.h:67
@ OPERAND_FIRST_GENERIC_IMM
Definition MCInstrDesc.h:76
@ OPERAND_LAST_GENERIC_IMM
Definition MCInstrDesc.h:78
This is an optimization pass for GlobalISel generic memory operations.
MaybeAlign getAlign(const CallInst &I, unsigned Index)
std::function< std::pair< unsigned, LLT >(const LegalityQuery &)> LegalizeMutation
std::function< bool(const LegalityQuery &)> LegalityPredicate
LLVM_ABI cl::opt< bool > DisableGISelLegalityCheck
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
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LegacyLegalizeActions::LegacyLegalizeAction Action
The action to take or the final answer.
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< MemDesc > MMODescrs
Operations which require memory can use this to place requirements on the memory type for each MMO.
ArrayRef< LLT > Types
LLVM_ABI raw_ostream & print(raw_ostream &OS) const
constexpr LegalityQuery(unsigned Opcode, ArrayRef< LLT > Types, ArrayRef< MemDesc > MMODescrs={})
The result of a query.
LegalizeAction Action
The action to take or the final answer.
LegalizeActionStep(LegacyLegalizeActionStep Step)
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