LLVM 23.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
132 : Opcode(Opcode), Types(Types), MMODescrs(MMODescrs) {}
133
134 LLVM_ABI raw_ostream &print(raw_ostream &OS) const;
135};
136
137/// The result of a query. It either indicates a final answer of Legal or
138/// Unsupported or describes an action that must be taken to make an operation
139/// more legal.
141 /// The action to take or the final answer.
143 /// If describing an action, the type index to change. Otherwise zero.
144 unsigned TypeIdx;
145 /// If describing an action, the new type for TypeIdx. Otherwise LLT{}.
147
151
152 bool operator==(const LegalizeActionStep &RHS) const {
153 return std::tie(Action, TypeIdx, NewType) ==
154 std::tie(RHS.Action, RHS.TypeIdx, RHS.NewType);
155 }
156};
157
158using LegalityPredicate = std::function<bool (const LegalityQuery &)>;
160 std::function<std::pair<unsigned, LLT>(const LegalityQuery &)>;
161
168
170 return Type0 == Other.Type0 && Type1 == Other.Type1 &&
171 Align == Other.Align && MemTy == Other.MemTy;
172 }
173
174 /// \returns true if this memory access is legal with for the access described
175 /// by \p Other (The alignment is sufficient for the size and result type).
177 return Type0 == Other.Type0 && Type1 == Other.Type1 &&
178 Align >= Other.Align &&
179 // FIXME: This perhaps should be stricter, but the current legality
180 // rules are written only considering the size.
181 MemTy.getSizeInBits() == Other.MemTy.getSizeInBits();
182 }
183};
184
185/// True iff P is false.
186template <typename Predicate> Predicate predNot(Predicate P) {
187 return [=](const LegalityQuery &Query) { return !P(Query); };
188}
189
190/// True iff P0 and P1 are true.
191template<typename Predicate>
193 return [=](const LegalityQuery &Query) {
194 return P0(Query) && P1(Query);
195 };
196}
197/// True iff all given predicates are true.
198template<typename Predicate, typename... Args>
200 return all(all(P0, P1), args...);
201}
202
203/// True iff P0 or P1 are true.
204template<typename Predicate>
206 return [=](const LegalityQuery &Query) {
207 return P0(Query) || P1(Query);
208 };
209}
210/// True iff any given predicates are true.
211template<typename Predicate, typename... Args>
213 return any(any(P0, P1), args...);
214}
215
216/// True iff the given type index is the specified type.
217LLVM_ABI LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit);
218/// True iff the given type index is one of the specified types.
219LLVM_ABI LegalityPredicate typeInSet(unsigned TypeIdx,
220 std::initializer_list<LLT> TypesInit);
221
222/// True iff the given type index is not the specified type.
223inline LegalityPredicate typeIsNot(unsigned TypeIdx, LLT Type) {
224 return [=](const LegalityQuery &Query) {
225 return Query.Types[TypeIdx] != Type;
226 };
227}
228
229/// True iff the given types for the given pair of type indexes is one of the
230/// specified type pairs.
232typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1,
233 std::initializer_list<std::pair<LLT, LLT>> TypesInit);
234/// True iff the given types for the given tuple of type indexes is one of the
235/// specified type tuple.
237typeTupleInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned Type2,
238 std::initializer_list<std::tuple<LLT, LLT, LLT>> TypesInit);
239/// True iff the given types for the given pair of type indexes is one of the
240/// specified type pairs.
242 unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx,
243 std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit);
244/// True iff the specified type index is a scalar.
245LLVM_ABI LegalityPredicate isScalar(unsigned TypeIdx);
246/// True iff the specified type index is a vector.
247LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx);
248/// True iff the specified type index is a pointer (with any address space).
249LLVM_ABI LegalityPredicate isPointer(unsigned TypeIdx);
250/// True iff the specified type index is a pointer with the specified address
251/// space.
252LLVM_ABI LegalityPredicate isPointer(unsigned TypeIdx, unsigned AddrSpace);
253/// True iff the specified type index is a vector of pointers (with any address
254/// space).
256
257/// True if the type index is a vector with element type \p EltTy
258LLVM_ABI LegalityPredicate elementTypeIs(unsigned TypeIdx, LLT EltTy);
259
260/// True iff the specified type index is a scalar that's narrower than the given
261/// size.
262LLVM_ABI LegalityPredicate scalarNarrowerThan(unsigned TypeIdx, unsigned Size);
263
264/// True iff the specified type index is a scalar that's wider than the given
265/// size.
266LLVM_ABI LegalityPredicate scalarWiderThan(unsigned TypeIdx, unsigned Size);
267
268/// True iff the specified type index is a scalar or vector with an element type
269/// that's narrower than the given size.
271 unsigned Size);
272
273/// True iff the specified type index is a vector with a number of elements
274/// that's greater than the given size.
276 unsigned Size);
277
278/// True iff the specified type index is a vector with a number of elements
279/// that's less than or equal to the given size.
281vectorElementCountIsLessThanOrEqualTo(unsigned TypeIdx, unsigned Size);
282
283/// True iff the specified type index is a scalar or a vector with an element
284/// type that's wider than the given size.
286 unsigned Size);
287
288/// True iff the specified type index is a scalar whose size is not a multiple
289/// of Size.
290LLVM_ABI LegalityPredicate sizeNotMultipleOf(unsigned TypeIdx, unsigned Size);
291
292/// True iff the specified type index is a scalar whose size is not a power of
293/// 2.
294LLVM_ABI LegalityPredicate sizeNotPow2(unsigned TypeIdx);
295
296/// True iff the specified type index is a scalar or vector whose element size
297/// is not a power of 2.
299
300/// True if the total bitwidth of the specified type index is \p Size bits.
301LLVM_ABI LegalityPredicate sizeIs(unsigned TypeIdx, unsigned Size);
302
303/// True iff the specified type indices are both the same bit size.
304LLVM_ABI LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1);
305
306/// True iff the first type index has a larger total bit size than second type
307/// index.
308LLVM_ABI LegalityPredicate largerThan(unsigned TypeIdx0, unsigned TypeIdx1);
309
310/// True iff the first type index has a smaller total bit size than second type
311/// index.
312LLVM_ABI LegalityPredicate smallerThan(unsigned TypeIdx0, unsigned TypeIdx1);
313
314/// True iff the specified MMO index has a size (rounded to bytes) that is not a
315/// power of 2.
317
318/// True iff the specified MMO index has a size that is not an even byte size,
319/// or that even byte size is not a power of 2.
321
322/// True iff the specified type index is a vector whose element count is not a
323/// power of 2.
325/// True iff the specified MMO index has at an atomic ordering of at Ordering or
326/// stronger.
328atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx, AtomicOrdering Ordering);
329} // end namespace LegalityPredicates
330
332/// Select this specific type for the given type index.
333LLVM_ABI LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
334
335/// Keep the same type as the given type index.
336LLVM_ABI LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx);
337
338/// Keep the same scalar or element type as the given type index.
340 unsigned FromTypeIdx);
341
342/// Keep the same scalar or element type as the given type.
343LLVM_ABI LegalizeMutation changeElementTo(unsigned TypeIdx, LLT Ty);
344
345/// Keep the same scalar or element type as \p TypeIdx, but take the number of
346/// elements from \p FromTypeIdx.
348 unsigned FromTypeIdx);
349
350/// Keep the same scalar or element type as \p TypeIdx, but take the number of
351/// elements from \p Ty.
353 ElementCount EC);
354
355/// Change the scalar size or element size to have the same scalar size as type
356/// index \p FromIndex. Unlike changeElementTo, this discards pointer types and
357/// only changes the size.
359 unsigned FromTypeIdx);
360
361/// Change the scalar size or element size to have the same scalar size as the
362/// type \p NewTy. Unlike changeElementTo, this discards pointer types and only
363/// changes the size.
364LLVM_ABI LegalizeMutation changeElementSizeTo(unsigned TypeIdx, LLT NewTy);
365
366/// Widen the scalar type or vector element type for the given type index to the
367/// next power of 2.
369 unsigned Min = 0);
370
371/// Widen the scalar type or vector element type for the given type index to
372/// next multiple of \p Size.
374 unsigned Size);
375
376/// Add more elements to the type for the given type index to the next power of
377/// 2.
379 unsigned Min = 0);
380/// Break up the vector type for the given type index into the element type.
381LLVM_ABI LegalizeMutation scalarize(unsigned TypeIdx);
382} // end namespace LegalizeMutations
383
384/// A single rule in a legalizer info ruleset.
385/// The specified action is chosen when the predicate is true. Where appropriate
386/// for the action (e.g. for WidenScalar) the new type is selected using the
387/// given mutator.
389 LegalityPredicate Predicate;
390 LegalizeAction Action;
391 LegalizeMutation Mutation;
392
393public:
395 LegalizeMutation Mutation = nullptr)
396 : Predicate(Predicate), Action(Action), Mutation(Mutation) {}
397
398 /// Test whether the LegalityQuery matches.
399 bool match(const LegalityQuery &Query) const {
400 return Predicate(Query);
401 }
402
403 LegalizeAction getAction() const { return Action; }
404
405 /// Determine the change to make.
406 std::pair<unsigned, LLT> determineMutation(const LegalityQuery &Query) const {
407 if (Mutation)
408 return Mutation(Query);
409 return std::make_pair(0, LLT{});
410 }
411};
412
414 /// When non-zero, the opcode we are an alias of
415 unsigned AliasOf = 0;
416 /// If true, there is another opcode that aliases this one
417 bool IsAliasedByAnother = false;
419
420#ifndef NDEBUG
421 /// If bit I is set, this rule set contains a rule that may handle (predicate
422 /// or perform an action upon (or both)) the type index I. The uncertainty
423 /// comes from free-form rules executing user-provided lambda functions. We
424 /// conservatively assume such rules do the right thing and cover all type
425 /// indices. The bitset is intentionally 1 bit wider than it absolutely needs
426 /// to be to distinguish such cases from the cases where all type indices are
427 /// individually handled.
432#endif
433
434 unsigned typeIdx(unsigned TypeIdx) {
435 assert(TypeIdx <=
437 "Type Index is out of bounds");
438#ifndef NDEBUG
439 TypeIdxsCovered.set(TypeIdx);
440#endif
441 return TypeIdx;
442 }
443
444 void markAllIdxsAsCovered() {
445#ifndef NDEBUG
446 TypeIdxsCovered.set();
447 ImmIdxsCovered.set();
448#endif
449 }
450
451 void add(const LegalizeRule &Rule) {
452 assert(AliasOf == 0 &&
453 "RuleSet is aliased, change the representative opcode instead");
454 Rules.push_back(Rule);
455 }
456
457 static bool always(const LegalityQuery &) { return true; }
458
459 /// Use the given action when the predicate is true.
460 /// Action should not be an action that requires mutation.
461 LegalizeRuleSet &actionIf(LegalizeAction Action,
463 add({Predicate, Action});
464 return *this;
465 }
466 /// Use the given action when the predicate is true.
467 /// Action should be an action that requires mutation.
470 add({Predicate, Action, Mutation});
471 return *this;
472 }
473 /// Use the given action when type index 0 is any type in the given list.
474 /// Action should not be an action that requires mutation.
475 LegalizeRuleSet &actionFor(LegalizeAction Action,
476 std::initializer_list<LLT> Types) {
477 using namespace LegalityPredicates;
478 return actionIf(Action, typeInSet(typeIdx(0), Types));
479 }
480 /// Use the given action when type index 0 is any type in the given list.
481 /// Action should be an action that requires mutation.
482 LegalizeRuleSet &actionFor(LegalizeAction Action,
483 std::initializer_list<LLT> Types,
485 using namespace LegalityPredicates;
486 return actionIf(Action, typeInSet(typeIdx(0), Types), Mutation);
487 }
488 /// Use the given action when type indexes 0 and 1 is any type pair in the
489 /// given list.
490 /// Action should not be an action that requires mutation.
491 LegalizeRuleSet &actionFor(LegalizeAction Action,
492 std::initializer_list<std::pair<LLT, LLT>> Types) {
493 using namespace LegalityPredicates;
494 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
495 }
496
498 actionFor(LegalizeAction Action,
499 std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
500 using namespace LegalityPredicates;
501 return actionIf(Action,
502 typeTupleInSet(typeIdx(0), typeIdx(1), typeIdx(2), Types));
503 }
504
505 /// Use the given action when type indexes 0 and 1 is any type pair in the
506 /// given list.
507 /// Action should be an action that requires mutation.
508 LegalizeRuleSet &actionFor(LegalizeAction Action,
509 std::initializer_list<std::pair<LLT, LLT>> Types,
511 using namespace LegalityPredicates;
512 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types),
513 Mutation);
514 }
515 /// Use the given action when type index 0 is any type in the given list and
516 /// imm index 0 is anything. Action should not be an action that requires
517 /// mutation.
518 LegalizeRuleSet &actionForTypeWithAnyImm(LegalizeAction Action,
519 std::initializer_list<LLT> Types) {
520 using namespace LegalityPredicates;
521 immIdx(0); // Inform verifier imm idx 0 is handled.
522 return actionIf(Action, typeInSet(typeIdx(0), Types));
523 }
524
525 LegalizeRuleSet &actionForTypeWithAnyImm(
526 LegalizeAction Action, std::initializer_list<std::pair<LLT, LLT>> Types) {
527 using namespace LegalityPredicates;
528 immIdx(0); // Inform verifier imm idx 0 is handled.
529 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
530 }
531
532 /// Use the given action when type indexes 0 and 1 are both in the given list.
533 /// That is, the type pair is in the cartesian product of the list.
534 /// Action should not be an action that requires mutation.
535 LegalizeRuleSet &actionForCartesianProduct(LegalizeAction Action,
536 std::initializer_list<LLT> Types) {
537 using namespace LegalityPredicates;
538 return actionIf(Action, all(typeInSet(typeIdx(0), Types),
539 typeInSet(typeIdx(1), Types)));
540 }
541 /// Use the given action when type indexes 0 and 1 are both in their
542 /// respective lists.
543 /// That is, the type pair is in the cartesian product of the lists
544 /// Action should not be an action that requires mutation.
546 actionForCartesianProduct(LegalizeAction Action,
547 std::initializer_list<LLT> Types0,
548 std::initializer_list<LLT> Types1) {
549 using namespace LegalityPredicates;
550 return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
551 typeInSet(typeIdx(1), Types1)));
552 }
553 /// Use the given action when type indexes 0, 1, and 2 are all in their
554 /// respective lists.
555 /// That is, the type triple is in the cartesian product of the lists
556 /// Action should not be an action that requires mutation.
557 LegalizeRuleSet &actionForCartesianProduct(
558 LegalizeAction Action, std::initializer_list<LLT> Types0,
559 std::initializer_list<LLT> Types1, std::initializer_list<LLT> Types2) {
560 using namespace LegalityPredicates;
561 return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
562 all(typeInSet(typeIdx(1), Types1),
563 typeInSet(typeIdx(2), Types2))));
564 }
565
566public:
567 LegalizeRuleSet() = default;
568
569 bool isAliasedByAnother() { return IsAliasedByAnother; }
570 void setIsAliasedByAnother() { IsAliasedByAnother = true; }
571 void aliasTo(unsigned Opcode) {
572 assert((AliasOf == 0 || AliasOf == Opcode) &&
573 "Opcode is already aliased to another opcode");
574 assert(Rules.empty() && "Aliasing will discard rules");
575 AliasOf = Opcode;
576 }
577 unsigned getAlias() const { return AliasOf; }
578
579 unsigned immIdx(unsigned ImmIdx) {
582 "Imm Index is out of bounds");
583#ifndef NDEBUG
584 ImmIdxsCovered.set(ImmIdx);
585#endif
586 return ImmIdx;
587 }
588
589 /// The instruction is legal if predicate is true.
591 // We have no choice but conservatively assume that the free-form
592 // user-provided Predicate properly handles all type indices:
593 markAllIdxsAsCovered();
594 return actionIf(LegalizeAction::Legal, Predicate);
595 }
596 /// The instruction is legal when type index 0 is any type in the given list.
597 LegalizeRuleSet &legalFor(std::initializer_list<LLT> Types) {
598 return actionFor(LegalizeAction::Legal, Types);
599 }
600 LegalizeRuleSet &legalFor(bool Pred, std::initializer_list<LLT> Types) {
601 if (!Pred)
602 return *this;
603 return actionFor(LegalizeAction::Legal, Types);
604 }
605 /// The instruction is legal when type indexes 0 and 1 is any type pair in the
606 /// given list.
607 LegalizeRuleSet &legalFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
608 return actionFor(LegalizeAction::Legal, Types);
609 }
611 std::initializer_list<std::pair<LLT, LLT>> Types) {
612 if (!Pred)
613 return *this;
614 return actionFor(LegalizeAction::Legal, Types);
615 }
617 legalFor(bool Pred, std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
618 if (!Pred)
619 return *this;
620 return actionFor(LegalizeAction::Legal, Types);
621 }
622 /// The instruction is legal when type index 0 is any type in the given list
623 /// and imm index 0 is anything.
624 LegalizeRuleSet &legalForTypeWithAnyImm(std::initializer_list<LLT> Types) {
625 markAllIdxsAsCovered();
626 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
627 }
628
630 std::initializer_list<std::pair<LLT, LLT>> Types) {
631 markAllIdxsAsCovered();
632 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
633 }
634
635 /// The instruction is legal when type indexes 0 and 1 along with the memory
636 /// size and minimum alignment is any type and size tuple in the given list.
638 std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
639 TypesAndMemDesc) {
640 return actionIf(LegalizeAction::Legal,
642 typeIdx(0), typeIdx(1), /*MMOIdx*/ 0, TypesAndMemDesc));
643 }
645 bool Pred, std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
646 TypesAndMemDesc) {
647 if (!Pred)
648 return *this;
649 return actionIf(LegalizeAction::Legal,
651 typeIdx(0), typeIdx(1), /*MMOIdx=*/0, TypesAndMemDesc));
652 }
653 /// The instruction is legal when type indexes 0 and 1 are both in the given
654 /// list. That is, the type pair is in the cartesian product of the list.
655 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types) {
656 return actionForCartesianProduct(LegalizeAction::Legal, Types);
657 }
658 /// The instruction is legal when type indexes 0 and 1 are both their
659 /// respective lists.
660 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
661 std::initializer_list<LLT> Types1) {
662 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
663 }
664 /// The instruction is legal when type indexes 0, 1, and 2 are both their
665 /// respective lists.
666 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
667 std::initializer_list<LLT> Types1,
668 std::initializer_list<LLT> Types2) {
669 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1,
670 Types2);
671 }
672
674 using namespace LegalizeMutations;
675 markAllIdxsAsCovered();
676 return actionIf(LegalizeAction::Legal, always);
677 }
678
679 /// The specified type index is coerced if predicate is true.
682 // We have no choice but conservatively assume that lowering with a
683 // free-form user provided Predicate properly handles all type indices:
684 markAllIdxsAsCovered();
685 return actionIf(LegalizeAction::Bitcast, Predicate, Mutation);
686 }
687
688 /// The instruction is lowered.
690 using namespace LegalizeMutations;
691 // We have no choice but conservatively assume that predicate-less lowering
692 // properly handles all type indices by design:
693 markAllIdxsAsCovered();
694 return actionIf(LegalizeAction::Lower, always);
695 }
696 /// The instruction is lowered if predicate is true. Keep type index 0 as the
697 /// same type.
699 using namespace LegalizeMutations;
700 // We have no choice but conservatively assume that lowering with a
701 // free-form user provided Predicate properly handles all type indices:
702 markAllIdxsAsCovered();
703 return actionIf(LegalizeAction::Lower, Predicate);
704 }
705 /// The instruction is lowered if predicate is true.
708 // We have no choice but conservatively assume that lowering with a
709 // free-form user provided Predicate properly handles all type indices:
710 markAllIdxsAsCovered();
711 return actionIf(LegalizeAction::Lower, Predicate, Mutation);
712 }
713 /// The instruction is lowered when type index 0 is any type in the given
714 /// list. Keep type index 0 as the same type.
715 LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types) {
716 return actionFor(LegalizeAction::Lower, Types);
717 }
718 /// The instruction is lowered when type index 0 is any type in the given
719 /// list.
720 LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types,
722 return actionFor(LegalizeAction::Lower, Types, Mutation);
723 }
724 /// The instruction is lowered when type indexes 0 and 1 is any type pair in
725 /// the given list. Keep type index 0 as the same type.
726 LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
727 return actionFor(LegalizeAction::Lower, Types);
728 }
729 /// The instruction is lowered when type indexes 0 and 1 is any type pair in
730 /// the given list, provided Predicate pred is true.
732 std::initializer_list<std::pair<LLT, LLT>> Types) {
733 if (!Pred)
734 return *this;
735 return actionFor(LegalizeAction::Lower, Types);
736 }
737 /// The instruction is lowered when type indexes 0 and 1 is any type pair in
738 /// the given list.
739 LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types,
741 return actionFor(LegalizeAction::Lower, Types, Mutation);
742 }
743 /// The instruction is lowered when type indexes 0 and 1 are both in their
744 /// respective lists.
745 LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
746 std::initializer_list<LLT> Types1) {
747 using namespace LegalityPredicates;
748 return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1);
749 }
750 /// The instruction is lowered when type indexes 0, 1, and 2 are all in
751 /// their respective lists.
752 LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
753 std::initializer_list<LLT> Types1,
754 std::initializer_list<LLT> Types2) {
755 using namespace LegalityPredicates;
756 return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1,
757 Types2);
758 }
759
760 /// The instruction is emitted as a library call.
762 using namespace LegalizeMutations;
763 // We have no choice but conservatively assume that predicate-less lowering
764 // properly handles all type indices by design:
765 markAllIdxsAsCovered();
766 return actionIf(LegalizeAction::Libcall, always);
767 }
768
769 /// Like legalIf, but for the Libcall action.
771 // We have no choice but conservatively assume that a libcall with a
772 // free-form user provided Predicate properly handles all type indices:
773 markAllIdxsAsCovered();
774 return actionIf(LegalizeAction::Libcall, Predicate);
775 }
776 LegalizeRuleSet &libcallFor(std::initializer_list<LLT> Types) {
777 return actionFor(LegalizeAction::Libcall, Types);
778 }
779 LegalizeRuleSet &libcallFor(bool Pred, std::initializer_list<LLT> Types) {
780 if (!Pred)
781 return *this;
782 return actionFor(LegalizeAction::Libcall, Types);
783 }
785 libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
786 return actionFor(LegalizeAction::Libcall, Types);
787 }
789 libcallFor(bool Pred, std::initializer_list<std::pair<LLT, LLT>> Types) {
790 if (!Pred)
791 return *this;
792 return actionFor(LegalizeAction::Libcall, Types);
793 }
795 libcallForCartesianProduct(std::initializer_list<LLT> Types) {
796 return actionForCartesianProduct(LegalizeAction::Libcall, Types);
797 }
799 libcallForCartesianProduct(std::initializer_list<LLT> Types0,
800 std::initializer_list<LLT> Types1) {
801 return actionForCartesianProduct(LegalizeAction::Libcall, Types0, Types1);
802 }
803
804 /// Widen the scalar to the one selected by the mutation if the predicate is
805 /// true.
808 // We have no choice but conservatively assume that an action with a
809 // free-form user provided Predicate properly handles all type indices:
810 markAllIdxsAsCovered();
811 return actionIf(LegalizeAction::WidenScalar, Predicate, Mutation);
812 }
813 /// Widen the scalar, specified in mutation, when type index 0 is any type in
814 /// the given list.
815 LegalizeRuleSet &widenScalarFor(std::initializer_list<LLT> Types,
817 return actionFor(LegalizeAction::WidenScalar, Types, Mutation);
818 }
819 /// Widen the scalar, specified in mutation, when type indexes 0 and 1 is any
820 /// type pair in the given list.
822 widenScalarFor(std::initializer_list<std::pair<LLT, LLT>> Types,
824 return actionFor(LegalizeAction::WidenScalar, Types, Mutation);
825 }
826
827 /// Narrow the scalar to the one selected by the mutation if the predicate is
828 /// true.
831 // We have no choice but conservatively assume that an action with a
832 // free-form user provided Predicate properly handles all type indices:
833 markAllIdxsAsCovered();
834 return actionIf(LegalizeAction::NarrowScalar, Predicate, Mutation);
835 }
836 /// Narrow the scalar, specified in mutation, when type indexes 0 and 1 is any
837 /// type pair in the given list.
839 narrowScalarFor(std::initializer_list<std::pair<LLT, LLT>> Types,
841 return actionFor(LegalizeAction::NarrowScalar, Types, Mutation);
842 }
843
844 /// Add more elements to reach the type selected by the mutation if the
845 /// predicate is true.
848 // We have no choice but conservatively assume that an action with a
849 // free-form user provided Predicate properly handles all type indices:
850 markAllIdxsAsCovered();
851 return actionIf(LegalizeAction::MoreElements, Predicate, Mutation);
852 }
853 /// Remove elements to reach the type selected by the mutation if the
854 /// predicate is true.
857 // We have no choice but conservatively assume that an action with a
858 // free-form user provided Predicate properly handles all type indices:
859 markAllIdxsAsCovered();
860 return actionIf(LegalizeAction::FewerElements, Predicate, Mutation);
861 }
862
863 /// The instruction is unsupported.
865 markAllIdxsAsCovered();
866 return actionIf(LegalizeAction::Unsupported, always);
867 }
869 return actionIf(LegalizeAction::Unsupported, Predicate);
870 }
871
872 LegalizeRuleSet &unsupportedFor(std::initializer_list<LLT> Types) {
873 return actionFor(LegalizeAction::Unsupported, Types);
874 }
875
877 return actionIf(LegalizeAction::Unsupported,
879 }
880
881 /// Lower a memory operation if the memory size, rounded to bytes, is not a
882 /// power of 2. For example, this will not trigger for s1 or s7, but will for
883 /// s24.
885 return actionIf(LegalizeAction::Lower,
887 }
888
889 /// Lower a memory operation if the memory access size is not a round power of
890 /// 2 byte size. This is stricter than lowerIfMemSizeNotPow2, and more likely
891 /// what you want (e.g. this will lower s1, s7 and s24).
893 return actionIf(LegalizeAction::Lower,
895 }
896
898 // We have no choice but conservatively assume that a custom action with a
899 // free-form user provided Predicate properly handles all type indices:
900 markAllIdxsAsCovered();
901 return actionIf(LegalizeAction::Custom, Predicate);
902 }
903 LegalizeRuleSet &customFor(std::initializer_list<LLT> Types) {
904 return actionFor(LegalizeAction::Custom, Types);
905 }
906 LegalizeRuleSet &customFor(bool Pred, std::initializer_list<LLT> Types) {
907 if (!Pred)
908 return *this;
909 return actionFor(LegalizeAction::Custom, Types);
910 }
911
912 /// The instruction is custom when type indexes 0 and 1 is any type pair in
913 /// the given list.
914 LegalizeRuleSet &customFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
915 return actionFor(LegalizeAction::Custom, Types);
916 }
918 std::initializer_list<std::pair<LLT, LLT>> Types) {
919 if (!Pred)
920 return *this;
921 return actionFor(LegalizeAction::Custom, Types);
922 }
923
924 LegalizeRuleSet &customForCartesianProduct(std::initializer_list<LLT> Types) {
925 return actionForCartesianProduct(LegalizeAction::Custom, Types);
926 }
927 /// The instruction is custom when type indexes 0 and 1 are both in their
928 /// respective lists.
930 customForCartesianProduct(std::initializer_list<LLT> Types0,
931 std::initializer_list<LLT> Types1) {
932 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
933 }
934 /// The instruction is custom when type indexes 0, 1, and 2 are all in
935 /// their respective lists.
937 customForCartesianProduct(std::initializer_list<LLT> Types0,
938 std::initializer_list<LLT> Types1,
939 std::initializer_list<LLT> Types2) {
940 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1,
941 Types2);
942 }
943
944 /// The instruction is custom when the predicate is true and type indexes 0
945 /// and 1 are all in their respective lists.
947 customForCartesianProduct(bool Pred, std::initializer_list<LLT> Types0,
948 std::initializer_list<LLT> Types1) {
949 if (!Pred)
950 return *this;
951 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
952 }
953
954 /// Unconditionally custom lower.
956 return customIf(always);
957 }
958
959 /// Widen the scalar to the next power of two that is at least MinSize.
960 /// No effect if the type is a power of two, except if the type is smaller
961 /// than MinSize, or if the type is a vector type.
963 unsigned MinSize = 0) {
964 using namespace LegalityPredicates;
965 return actionIf(
966 LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
968 }
969
970 /// Widen the scalar to the next multiple of Size. No effect if the
971 /// type is not a scalar or is a multiple of Size.
973 unsigned Size) {
974 using namespace LegalityPredicates;
975 return actionIf(
976 LegalizeAction::WidenScalar, sizeNotMultipleOf(typeIdx(TypeIdx), Size),
978 }
979
980 /// Widen the scalar or vector element type to the next power of two that is
981 /// at least MinSize. No effect if the scalar size is a power of two.
983 unsigned MinSize = 0) {
984 using namespace LegalityPredicates;
985 return actionIf(
986 LegalizeAction::WidenScalar, scalarOrEltSizeNotPow2(typeIdx(TypeIdx)),
988 }
989
990 /// Widen the scalar or vector element type to the next power of two that is
991 /// at least MinSize. No effect if the scalar size is a power of two.
993 unsigned MinSize = 0) {
994 using namespace LegalityPredicates;
995 return actionIf(
996 LegalizeAction::WidenScalar,
997 any(scalarOrEltNarrowerThan(TypeIdx, MinSize),
998 scalarOrEltSizeNotPow2(typeIdx(TypeIdx))),
1000 }
1001
1003 using namespace LegalityPredicates;
1004 return actionIf(LegalizeAction::NarrowScalar, isScalar(typeIdx(TypeIdx)),
1005 Mutation);
1006 }
1007
1008 LegalizeRuleSet &scalarize(unsigned TypeIdx) {
1009 using namespace LegalityPredicates;
1010 return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)),
1012 }
1013
1015 using namespace LegalityPredicates;
1016 return actionIf(LegalizeAction::FewerElements,
1017 all(Predicate, isVector(typeIdx(TypeIdx))),
1019 }
1020
1021 /// Ensure the scalar or element is at least as wide as Ty.
1022 LegalizeRuleSet &minScalarOrElt(unsigned TypeIdx, const LLT Ty) {
1023 using namespace LegalityPredicates;
1024 using namespace LegalizeMutations;
1025 return actionIf(LegalizeAction::WidenScalar,
1026 scalarOrEltNarrowerThan(TypeIdx, Ty.getScalarSizeInBits()),
1027 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1028 }
1029
1030 /// Ensure the scalar or element is at least as wide as Ty.
1032 unsigned TypeIdx, const LLT Ty) {
1033 using namespace LegalityPredicates;
1034 using namespace LegalizeMutations;
1035 return actionIf(LegalizeAction::WidenScalar,
1036 all(Predicate, scalarOrEltNarrowerThan(
1037 TypeIdx, Ty.getScalarSizeInBits())),
1038 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1039 }
1040
1041 /// Ensure the vector size is at least as wide as VectorSize by promoting the
1042 /// element.
1044 unsigned VectorSize) {
1045 using namespace LegalityPredicates;
1046 using namespace LegalizeMutations;
1047 return actionIf(
1048 LegalizeAction::WidenScalar,
1049 [=](const LegalityQuery &Query) {
1050 const LLT VecTy = Query.Types[TypeIdx];
1051 return VecTy.isFixedVector() && VecTy.getSizeInBits() < VectorSize;
1052 },
1053 [=](const LegalityQuery &Query) {
1054 const LLT VecTy = Query.Types[TypeIdx];
1055 unsigned NumElts = VecTy.getNumElements();
1056 unsigned MinSize = VectorSize / NumElts;
1057 LLT NewTy = LLT::fixed_vector(
1058 NumElts, VecTy.getElementType().changeElementSize(MinSize));
1059 return std::make_pair(TypeIdx, NewTy);
1060 });
1061 }
1062
1063 /// Ensure the scalar is at least as wide as Ty.
1064 LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT Ty) {
1065 using namespace LegalityPredicates;
1066 using namespace LegalizeMutations;
1067 return actionIf(LegalizeAction::WidenScalar,
1068 scalarNarrowerThan(TypeIdx, Ty.getSizeInBits()),
1069 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1070 }
1071 LegalizeRuleSet &minScalar(bool Pred, unsigned TypeIdx, const LLT Ty) {
1072 if (!Pred)
1073 return *this;
1074 return minScalar(TypeIdx, Ty);
1075 }
1076
1077 /// Ensure the scalar is at least as wide as Ty if condition is met.
1079 const LLT Ty) {
1080 using namespace LegalityPredicates;
1081 using namespace LegalizeMutations;
1082 return actionIf(
1083 LegalizeAction::WidenScalar,
1084 [=](const LegalityQuery &Query) {
1085 const LLT QueryTy = Query.Types[TypeIdx];
1086 return QueryTy.isScalar() &&
1087 QueryTy.getSizeInBits() < Ty.getSizeInBits() &&
1088 Predicate(Query);
1089 },
1090 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1091 }
1092
1093 /// Ensure the scalar is at most as wide as Ty.
1094 LegalizeRuleSet &maxScalarOrElt(unsigned TypeIdx, const LLT Ty) {
1095 using namespace LegalityPredicates;
1096 using namespace LegalizeMutations;
1097 return actionIf(LegalizeAction::NarrowScalar,
1098 scalarOrEltWiderThan(TypeIdx, Ty.getScalarSizeInBits()),
1099 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1100 }
1101
1102 /// Ensure the scalar is at most as wide as Ty.
1103 LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT Ty) {
1104 using namespace LegalityPredicates;
1105 using namespace LegalizeMutations;
1106 return actionIf(LegalizeAction::NarrowScalar,
1107 scalarWiderThan(TypeIdx, Ty.getSizeInBits()),
1108 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1109 }
1110
1111 /// Conditionally limit the maximum size of the scalar.
1112 /// For example, when the maximum size of one type depends on the size of
1113 /// another such as extracting N bits from an M bit container.
1115 const LLT Ty) {
1116 using namespace LegalityPredicates;
1117 using namespace LegalizeMutations;
1118 return actionIf(
1119 LegalizeAction::NarrowScalar,
1120 [=](const LegalityQuery &Query) {
1121 const LLT QueryTy = Query.Types[TypeIdx];
1122 return QueryTy.isScalar() &&
1123 QueryTy.getSizeInBits() > Ty.getSizeInBits() &&
1124 Predicate(Query);
1125 },
1126 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1127 }
1128
1129 /// Limit the range of scalar sizes to MinTy and MaxTy.
1130 LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT MinTy,
1131 const LLT MaxTy) {
1132 assert(MinTy.isScalar() && MaxTy.isScalar() && "Expected scalar types");
1133 return minScalar(TypeIdx, MinTy).maxScalar(TypeIdx, MaxTy);
1134 }
1135
1136 LegalizeRuleSet &clampScalar(bool Pred, unsigned TypeIdx, const LLT MinTy,
1137 const LLT MaxTy) {
1138 if (!Pred)
1139 return *this;
1140 return clampScalar(TypeIdx, MinTy, MaxTy);
1141 }
1142
1143 /// Limit the range of scalar sizes to MinTy and MaxTy.
1144 LegalizeRuleSet &clampScalarOrElt(unsigned TypeIdx, const LLT MinTy,
1145 const LLT MaxTy) {
1146 return minScalarOrElt(TypeIdx, MinTy).maxScalarOrElt(TypeIdx, MaxTy);
1147 }
1148
1149 /// Widen the scalar to match the size of another.
1150 LegalizeRuleSet &minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx) {
1151 typeIdx(TypeIdx);
1152 return actionIf(
1153 LegalizeAction::WidenScalar,
1154 [=](const LegalityQuery &Query) {
1155 return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
1156 Query.Types[TypeIdx].getSizeInBits();
1157 },
1158 LegalizeMutations::changeElementSizeTo(TypeIdx, LargeTypeIdx));
1159 }
1160
1161 /// Narrow the scalar to match the size of another.
1162 LegalizeRuleSet &maxScalarSameAs(unsigned TypeIdx, unsigned NarrowTypeIdx) {
1163 typeIdx(TypeIdx);
1164 return actionIf(
1165 LegalizeAction::NarrowScalar,
1166 [=](const LegalityQuery &Query) {
1167 return Query.Types[NarrowTypeIdx].getScalarSizeInBits() <
1168 Query.Types[TypeIdx].getSizeInBits();
1169 },
1170 LegalizeMutations::changeElementSizeTo(TypeIdx, NarrowTypeIdx));
1171 }
1172
1173 /// Change the type \p TypeIdx to have the same scalar size as type \p
1174 /// SameSizeIdx.
1175 LegalizeRuleSet &scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx) {
1176 return minScalarSameAs(TypeIdx, SameSizeIdx)
1177 .maxScalarSameAs(TypeIdx, SameSizeIdx);
1178 }
1179
1180 /// Conditionally widen the scalar or elt to match the size of another.
1182 unsigned TypeIdx, unsigned LargeTypeIdx) {
1183 typeIdx(TypeIdx);
1184 return widenScalarIf(
1185 [=](const LegalityQuery &Query) {
1186 return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
1187 Query.Types[TypeIdx].getScalarSizeInBits() &&
1188 Predicate(Query);
1189 },
1190 [=](const LegalityQuery &Query) {
1191 LLT T = Query.Types[TypeIdx].changeElementSize(
1192 Query.Types[LargeTypeIdx].getScalarSizeInBits());
1193 return std::make_pair(TypeIdx, T);
1194 });
1195 }
1196
1197 /// Conditionally narrow the scalar or elt to match the size of another.
1199 unsigned TypeIdx,
1200 unsigned SmallTypeIdx) {
1201 typeIdx(TypeIdx);
1202 return narrowScalarIf(
1203 [=](const LegalityQuery &Query) {
1204 return Query.Types[SmallTypeIdx].getScalarSizeInBits() <
1205 Query.Types[TypeIdx].getScalarSizeInBits() &&
1206 Predicate(Query);
1207 },
1208 [=](const LegalityQuery &Query) {
1209 LLT T = Query.Types[SmallTypeIdx];
1210 return std::make_pair(TypeIdx, T);
1211 });
1212 }
1213
1214 /// Add more elements to the vector to reach the next power of two.
1215 /// No effect if the type is not a vector or the element count is a power of
1216 /// two.
1218 using namespace LegalityPredicates;
1219 return actionIf(LegalizeAction::MoreElements,
1220 numElementsNotPow2(typeIdx(TypeIdx)),
1222 }
1223
1224 /// Limit the number of elements in EltTy vectors to at least MinElements.
1225 LegalizeRuleSet &clampMinNumElements(unsigned TypeIdx, const LLT EltTy,
1226 unsigned MinElements) {
1227 // Mark the type index as covered:
1228 typeIdx(TypeIdx);
1229 return actionIf(
1230 LegalizeAction::MoreElements,
1231 [=](const LegalityQuery &Query) {
1232 LLT VecTy = Query.Types[TypeIdx];
1233 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1234 VecTy.getNumElements() < MinElements;
1235 },
1236 [=](const LegalityQuery &Query) {
1237 LLT VecTy = Query.Types[TypeIdx];
1238 return std::make_pair(
1239 TypeIdx, LLT::fixed_vector(MinElements, VecTy.getElementType()));
1240 });
1241 }
1242
1243 /// Set number of elements to nearest larger multiple of NumElts.
1244 LegalizeRuleSet &alignNumElementsTo(unsigned TypeIdx, const LLT EltTy,
1245 unsigned NumElts) {
1246 typeIdx(TypeIdx);
1247 return actionIf(
1248 LegalizeAction::MoreElements,
1249 [=](const LegalityQuery &Query) {
1250 LLT VecTy = Query.Types[TypeIdx];
1251 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1252 (VecTy.getNumElements() % NumElts != 0);
1253 },
1254 [=](const LegalityQuery &Query) {
1255 LLT VecTy = Query.Types[TypeIdx];
1256 unsigned NewSize = alignTo(VecTy.getNumElements(), NumElts);
1257 return std::make_pair(
1258 TypeIdx, LLT::fixed_vector(NewSize, VecTy.getElementType()));
1259 });
1260 }
1261
1262 /// Limit the number of elements in EltTy vectors to at most MaxElements.
1263 LegalizeRuleSet &clampMaxNumElements(unsigned TypeIdx, const LLT EltTy,
1264 unsigned MaxElements) {
1265 // Mark the type index as covered:
1266 typeIdx(TypeIdx);
1267 return actionIf(
1268 LegalizeAction::FewerElements,
1269 [=](const LegalityQuery &Query) {
1270 LLT VecTy = Query.Types[TypeIdx];
1271 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1272 VecTy.getNumElements() > MaxElements;
1273 },
1274 [=](const LegalityQuery &Query) {
1275 LLT VecTy = Query.Types[TypeIdx];
1276 LLT NewTy = LLT::scalarOrVector(ElementCount::getFixed(MaxElements),
1277 VecTy.getElementType());
1278 return std::make_pair(TypeIdx, NewTy);
1279 });
1280 }
1281 /// Limit the number of elements for the given vectors to at least MinTy's
1282 /// number of elements and at most MaxTy's number of elements.
1283 ///
1284 /// No effect if the type is not a vector or does not have the same element
1285 /// type as the constraints.
1286 /// The element type of MinTy and MaxTy must match.
1287 LegalizeRuleSet &clampNumElements(unsigned TypeIdx, const LLT MinTy,
1288 const LLT MaxTy) {
1289 assert(MinTy.getElementType() == MaxTy.getElementType() &&
1290 "Expected element types to agree");
1291
1292 assert((!MinTy.isScalableVector() && !MaxTy.isScalableVector()) &&
1293 "Unexpected scalable vectors");
1294
1295 const LLT EltTy = MinTy.getElementType();
1296 return clampMinNumElements(TypeIdx, EltTy, MinTy.getNumElements())
1297 .clampMaxNumElements(TypeIdx, EltTy, MaxTy.getNumElements());
1298 }
1299
1300 /// Express \p EltTy vectors strictly using vectors with \p NumElts elements
1301 /// (or scalars when \p NumElts equals 1).
1302 /// First pad with undef elements to nearest larger multiple of \p NumElts.
1303 /// Then perform split with all sub-instructions having the same type.
1304 /// Using clampMaxNumElements (non-strict) can result in leftover instruction
1305 /// with different type (fewer elements then \p NumElts or scalar).
1306 /// No effect if the type is not a vector.
1307 LegalizeRuleSet &clampMaxNumElementsStrict(unsigned TypeIdx, const LLT EltTy,
1308 unsigned NumElts) {
1309 return alignNumElementsTo(TypeIdx, EltTy, NumElts)
1310 .clampMaxNumElements(TypeIdx, EltTy, NumElts);
1311 }
1312
1313 /// Check if there is no type index which is obviously not handled by the
1314 /// LegalizeRuleSet in any way at all.
1315 /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
1316 LLVM_ABI bool verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const;
1317 /// Check if there is no imm index which is obviously not handled by the
1318 /// LegalizeRuleSet in any way at all.
1319 /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
1320 LLVM_ABI bool verifyImmIdxsCoverage(unsigned NumImmIdxs) const;
1321
1322 /// Apply the ruleset to the given LegalityQuery.
1323 LLVM_ABI LegalizeActionStep apply(const LegalityQuery &Query) const;
1324};
1325
1327public:
1328 virtual ~LegalizerInfo() = default;
1329
1330 unsigned getOpcodeIdxForOpcode(unsigned Opcode) const;
1331 unsigned getActionDefinitionsIdx(unsigned Opcode) const;
1332
1333 /// Perform simple self-diagnostic and assert if there is anything obviously
1334 /// wrong with the actions set up.
1335 void verify(const MCInstrInfo &MII) const;
1336
1337 /// Get the action definitions for the given opcode. Use this to run a
1338 /// LegalityQuery through the definitions.
1339 const LegalizeRuleSet &getActionDefinitions(unsigned Opcode) const;
1340
1341 /// Get the action definition builder for the given opcode. Use this to define
1342 /// the action definitions.
1343 ///
1344 /// It is an error to request an opcode that has already been requested by the
1345 /// multiple-opcode variant.
1347
1348 /// Get the action definition builder for the given set of opcodes. Use this
1349 /// to define the action definitions for multiple opcodes at once. The first
1350 /// opcode given will be considered the representative opcode and will hold
1351 /// the definitions whereas the other opcodes will be configured to refer to
1352 /// the representative opcode. This lowers memory requirements and very
1353 /// slightly improves performance.
1354 ///
1355 /// It would be very easy to introduce unexpected side-effects as a result of
1356 /// this aliasing if it were permitted to request different but intersecting
1357 /// sets of opcodes but that is difficult to keep track of. It is therefore an
1358 /// error to request the same opcode twice using this API, to request an
1359 /// opcode that already has definitions, or to use the single-opcode API on an
1360 /// opcode that has already been requested by this API.
1362 getActionDefinitionsBuilder(std::initializer_list<unsigned> Opcodes);
1363 void aliasActionDefinitions(unsigned OpcodeTo, unsigned OpcodeFrom);
1364
1365 /// Determine what action should be taken to legalize the described
1366 /// instruction. Requires computeTables to have been called.
1367 ///
1368 /// \returns a description of the next legalization step to perform.
1369 LegalizeActionStep getAction(const LegalityQuery &Query) const;
1370
1371 /// Determine what action should be taken to legalize the given generic
1372 /// instruction.
1373 ///
1374 /// \returns a description of the next legalization step to perform.
1376 const MachineRegisterInfo &MRI) const;
1377
1378 bool isLegal(const LegalityQuery &Query) const {
1379 return getAction(Query).Action == LegalizeAction::Legal;
1380 }
1381
1382 bool isLegalOrCustom(const LegalityQuery &Query) const {
1383 auto Action = getAction(Query).Action;
1384 return Action == LegalizeAction::Legal || Action == LegalizeAction::Custom;
1385 }
1386
1387 bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
1388 bool isLegalOrCustom(const MachineInstr &MI,
1389 const MachineRegisterInfo &MRI) const;
1390
1391 /// Called for instructions with the Custom LegalizationAction.
1393 LostDebugLocObserver &LocObserver) const {
1394 llvm_unreachable("must implement this if custom action is used");
1395 }
1396
1397 /// \returns true if MI is either legal or has been legalized and false if not
1398 /// legal.
1399 /// Return true if MI is either legal or has been legalized and false
1400 /// if not legal.
1402 MachineInstr &MI) const {
1403 return true;
1404 }
1405
1406 /// Return the opcode (SEXT/ZEXT/ANYEXT) that should be performed while
1407 /// widening a constant of type SmallTy which targets can override.
1408 /// For eg, the DAG does (SmallTy.isByteSized() ? G_SEXT : G_ZEXT) which
1409 /// will be the default.
1410 virtual unsigned getExtOpcodeForWideningConstant(LLT SmallTy) const;
1411
1412private:
1413 static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
1414 static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
1415
1416 LegalizeRuleSet RulesForOpcode[LastOp - FirstOp + 1];
1417};
1418
1419#ifndef NDEBUG
1420/// Checks that MIR is fully legal, returns an illegal instruction if it's not,
1421/// nullptr otherwise
1422const MachineInstr *machineFunctionIsIllegal(const MachineFunction &MF);
1423#endif
1424
1425} // end namespace llvm.
1426
1427#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 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 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.
@ 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< 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.
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