LLVM 24.0.0git
LegalizerInfo.h
Go to the documentation of this file.
1//===- llvm/CodeGen/GlobalISel/LegalizerInfo.h ------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// Interface for Targets to specify which operations they can successfully
10/// select and how the others should be expanded most efficiently.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
15#define LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
16
22#include "llvm/MC/MCInstrDesc.h"
26#include <cassert>
27#include <cstdint>
28#include <tuple>
29#include <utility>
30
31namespace llvm {
32
34
35class MachineFunction;
36class raw_ostream;
37class LegalizerHelper;
39class MachineInstr;
41class MCInstrInfo;
42
43namespace LegalizeActions {
44enum LegalizeAction : std::uint8_t {
45 /// The operation is expected to be selectable directly by the target, and
46 /// no transformation is necessary.
48
49 /// The operation should be synthesized from multiple instructions acting on
50 /// a narrower scalar base-type. For example a 64-bit add might be
51 /// implemented in terms of 32-bit add-with-carry.
53
54 /// The operation should be implemented in terms of a wider scalar
55 /// base-type. For example a <2 x s8> add could be implemented as a <2
56 /// x s32> add (ignoring the high bits).
58
59 /// The (vector) operation should be implemented by splitting it into
60 /// sub-vectors where the operation is legal. For example a <8 x s64> add
61 /// might be implemented as 4 separate <2 x s64> adds. There can be a leftover
62 /// if there are not enough elements for last sub-vector e.g. <7 x s64> add
63 /// will be implemented as 3 separate <2 x s64> adds and one s64 add. Leftover
64 /// types can be avoided by doing MoreElements first.
66
67 /// The (vector) operation should be implemented by widening the input
68 /// vector and ignoring the lanes added by doing so. For example <2 x i8> is
69 /// rarely legal, but you might perform an <8 x i8> and then only look at
70 /// the first two results.
72
73 /// Perform the operation on a different, but equivalently sized type.
75
76 /// The operation itself must be expressed in terms of simpler actions on
77 /// this target. E.g. a SREM replaced by an SDIV and subtraction.
79
80 /// The operation should be implemented as a call to some kind of runtime
81 /// support library. For example this usually happens on machines that don't
82 /// support floating-point operations natively.
84
85 /// The target wants to do something special with this combination of
86 /// operand and type. A callback will be issued when it is needed.
88
89 /// This operation is completely unsupported on the target.
91};
92} // end namespace LegalizeActions
93LLVM_ABI raw_ostream &operator<<(raw_ostream &OS,
95
97
98/// The LegalityQuery object bundles together all the information that's needed
99/// to decide whether a given operation is legal or not.
100/// For efficiency, it doesn't make a copy of Types so care must be taken not
101/// to free it before using the query.
103 unsigned Opcode;
105
106 struct MemDesc {
109 AtomicOrdering Ordering; //< For cmpxchg this is the success ordering.
110 AtomicOrdering FailureOrdering; //< For cmpxchg, otherwise NotAtomic.
111
112 MemDesc() = default;
118 : MemDesc(MMO.getMemoryType(), MMO.getAlign().value() * 8,
119 MMO.getSuccessOrdering(), MMO.getFailureOrdering()) {}
120 };
121
122 /// Operations which require memory can use this to place requirements on the
123 /// memory type for each MMO.
125
127
131 : 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
330/// True iff the immediate at the given index has the specified value.
331LLVM_ABI LegalityPredicate immIs(unsigned ImmIdx, int64_t Imm);
332/// True iff the immediate at the given index has one of the specified values.
333LLVM_ABI LegalityPredicate immInSet(unsigned ImmIdx,
334 std::initializer_list<int64_t> ImmsInit);
335/// True iff the immediate at the given index does not have the specified value.
336LLVM_ABI LegalityPredicate immIsNot(unsigned ImmIdx, int64_t Imm);
337} // end namespace LegalityPredicates
338
340/// Select this specific type for the given type index.
341LLVM_ABI LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
342
343/// Keep the same type as the given type index.
344LLVM_ABI LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx);
345
346/// Keep the same scalar or element type as the given type index.
348 unsigned FromTypeIdx);
349
350/// Keep the same scalar or element type as the given type.
351LLVM_ABI LegalizeMutation changeElementTo(unsigned TypeIdx, LLT Ty);
352
353/// Keep the same scalar or element type as \p TypeIdx, but take the number of
354/// elements from \p FromTypeIdx.
356 unsigned FromTypeIdx);
357
358/// Keep the same scalar or element type as \p TypeIdx, but take the number of
359/// elements from \p Ty.
361 ElementCount EC);
362
363/// Change the scalar size or element size to have the same scalar size as type
364/// index \p FromIndex. Unlike changeElementTo, this discards pointer types and
365/// only changes the size.
367 unsigned FromTypeIdx);
368
369/// Change the scalar size or element size to have the same scalar size as the
370/// type \p NewTy. Unlike changeElementTo, this discards pointer types and only
371/// changes the size.
372LLVM_ABI LegalizeMutation changeElementSizeTo(unsigned TypeIdx, LLT NewTy);
373
374/// Widen the scalar type or vector element type for the given type index to the
375/// next power of 2.
377 unsigned Min = 0);
378
379/// Widen the scalar type or vector element type for the given type index to
380/// next multiple of \p Size.
382 unsigned Size);
383
384/// Add more elements to the type for the given type index to the next power of
385/// 2.
387 unsigned Min = 0);
388/// Break up the vector type for the given type index into the element type.
389LLVM_ABI LegalizeMutation scalarize(unsigned TypeIdx);
390} // end namespace LegalizeMutations
391
392/// A single rule in a legalizer info ruleset.
393/// The specified action is chosen when the predicate is true. Where appropriate
394/// for the action (e.g. for WidenScalar) the new type is selected using the
395/// given mutator.
397 LegalityPredicate Predicate;
398 LegalizeAction Action;
399 LegalizeMutation Mutation;
400
401public:
403 LegalizeMutation Mutation = nullptr)
404 : Predicate(Predicate), Action(Action), Mutation(Mutation) {}
405
406 /// Test whether the LegalityQuery matches.
407 bool match(const LegalityQuery &Query) const {
408 return Predicate(Query);
409 }
410
411 LegalizeAction getAction() const { return Action; }
412
413 /// Determine the change to make.
414 std::pair<unsigned, LLT> determineMutation(const LegalityQuery &Query) const {
415 if (Mutation)
416 return Mutation(Query);
417 return std::make_pair(0, LLT{});
418 }
419};
420
422 /// When non-zero, the opcode we are an alias of
423 unsigned AliasOf = 0;
424 /// If true, there is another opcode that aliases this one
425 bool IsAliasedByAnother = false;
427
428#ifndef NDEBUG
429 /// If bit I is set, this rule set contains a rule that may handle (predicate
430 /// or perform an action upon (or both)) the type index I. The uncertainty
431 /// comes from free-form rules executing user-provided lambda functions. We
432 /// conservatively assume such rules do the right thing and cover all type
433 /// indices. The bitset is intentionally 1 bit wider than it absolutely needs
434 /// to be to distinguish such cases from the cases where all type indices are
435 /// individually handled.
440#endif
441
442 unsigned typeIdx(unsigned TypeIdx) {
443 assert(TypeIdx <=
445 "Type Index is out of bounds");
446#ifndef NDEBUG
447 TypeIdxsCovered.set(TypeIdx);
448#endif
449 return TypeIdx;
450 }
451
452 void markAllIdxsAsCovered() {
453#ifndef NDEBUG
454 TypeIdxsCovered.set();
455 ImmIdxsCovered.set();
456#endif
457 }
458
459 void add(const LegalizeRule &Rule) {
460 assert(AliasOf == 0 &&
461 "RuleSet is aliased, change the representative opcode instead");
462 Rules.push_back(Rule);
463 }
464
465 static bool always(const LegalityQuery &) { return true; }
466
467 /// Use the given action when the predicate is true.
468 /// Action should not be an action that requires mutation.
469 LegalizeRuleSet &actionIf(LegalizeAction Action,
471 add({Predicate, Action});
472 return *this;
473 }
474 /// Use the given action when the predicate is true.
475 /// Action should be an action that requires mutation.
478 add({Predicate, Action, Mutation});
479 return *this;
480 }
481 /// Use the given action when type index 0 is any type in the given list.
482 /// Action should not be an action that requires mutation.
483 LegalizeRuleSet &actionFor(LegalizeAction Action,
484 std::initializer_list<LLT> Types) {
485 using namespace LegalityPredicates;
486 return actionIf(Action, typeInSet(typeIdx(0), Types));
487 }
488 /// Use the given action when type index 0 is any type in the given list.
489 /// Action should be an action that requires mutation.
490 LegalizeRuleSet &actionFor(LegalizeAction Action,
491 std::initializer_list<LLT> Types,
493 using namespace LegalityPredicates;
494 return actionIf(Action, typeInSet(typeIdx(0), Types), Mutation);
495 }
496 /// Use the given action when type indexes 0 and 1 is any type pair in the
497 /// given list.
498 /// Action should not be an action that requires mutation.
499 LegalizeRuleSet &actionFor(LegalizeAction Action,
500 std::initializer_list<std::pair<LLT, LLT>> Types) {
501 using namespace LegalityPredicates;
502 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
503 }
504
506 actionFor(LegalizeAction Action,
507 std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
508 using namespace LegalityPredicates;
509 return actionIf(Action,
510 typeTupleInSet(typeIdx(0), typeIdx(1), typeIdx(2), Types));
511 }
512
513 /// Use the given action when type indexes 0 and 1 is any type pair in the
514 /// given list.
515 /// Action should be an action that requires mutation.
516 LegalizeRuleSet &actionFor(LegalizeAction Action,
517 std::initializer_list<std::pair<LLT, LLT>> Types,
519 using namespace LegalityPredicates;
520 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types),
521 Mutation);
522 }
523 /// Use the given action when type index 0 is any type in the given list and
524 /// imm index 0 is anything. Action should not be an action that requires
525 /// mutation.
526 LegalizeRuleSet &actionForTypeWithAnyImm(LegalizeAction Action,
527 std::initializer_list<LLT> Types) {
528 using namespace LegalityPredicates;
529 immIdx(0); // Inform verifier imm idx 0 is handled.
530 return actionIf(Action, typeInSet(typeIdx(0), Types));
531 }
532
533 LegalizeRuleSet &actionForTypeWithAnyImm(
534 LegalizeAction Action, std::initializer_list<std::pair<LLT, LLT>> Types) {
535 using namespace LegalityPredicates;
536 immIdx(0); // Inform verifier imm idx 0 is handled.
537 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
538 }
539
540 /// Use the given action when type indexes 0 and 1 are both in the given list.
541 /// That is, the type pair is in the cartesian product of the list.
542 /// Action should not be an action that requires mutation.
543 LegalizeRuleSet &actionForCartesianProduct(LegalizeAction Action,
544 std::initializer_list<LLT> Types) {
545 using namespace LegalityPredicates;
546 return actionIf(Action, all(typeInSet(typeIdx(0), Types),
547 typeInSet(typeIdx(1), Types)));
548 }
549 /// Use the given action when type indexes 0 and 1 are both in their
550 /// respective lists.
551 /// That is, the type pair is in the cartesian product of the lists
552 /// Action should not be an action that requires mutation.
554 actionForCartesianProduct(LegalizeAction Action,
555 std::initializer_list<LLT> Types0,
556 std::initializer_list<LLT> Types1) {
557 using namespace LegalityPredicates;
558 return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
559 typeInSet(typeIdx(1), Types1)));
560 }
561 /// Use the given action when type indexes 0, 1, and 2 are all in their
562 /// respective lists.
563 /// That is, the type triple is in the cartesian product of the lists
564 /// Action should not be an action that requires mutation.
565 LegalizeRuleSet &actionForCartesianProduct(
566 LegalizeAction Action, std::initializer_list<LLT> Types0,
567 std::initializer_list<LLT> Types1, std::initializer_list<LLT> Types2) {
568 using namespace LegalityPredicates;
569 return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
570 all(typeInSet(typeIdx(1), Types1),
571 typeInSet(typeIdx(2), Types2))));
572 }
573
574public:
575 LegalizeRuleSet() = default;
576
577 bool isAliasedByAnother() { return IsAliasedByAnother; }
578 void setIsAliasedByAnother() { IsAliasedByAnother = true; }
579 void aliasTo(unsigned Opcode) {
580 assert((AliasOf == 0 || AliasOf == Opcode) &&
581 "Opcode is already aliased to another opcode");
582 assert(Rules.empty() && "Aliasing will discard rules");
583 AliasOf = Opcode;
584 }
585 unsigned getAlias() const { return AliasOf; }
586
587 unsigned immIdx(unsigned ImmIdx) {
590 "Imm Index is out of bounds");
591#ifndef NDEBUG
592 ImmIdxsCovered.set(ImmIdx);
593#endif
594 return ImmIdx;
595 }
596
597 /// The instruction is legal if predicate is true.
599 // We have no choice but conservatively assume that the free-form
600 // user-provided Predicate properly handles all type indices:
601 markAllIdxsAsCovered();
602 return actionIf(LegalizeAction::Legal, Predicate);
603 }
604 /// The instruction is legal when type index 0 is any type in the given list.
605 LegalizeRuleSet &legalFor(std::initializer_list<LLT> Types) {
606 return actionFor(LegalizeAction::Legal, Types);
607 }
608 LegalizeRuleSet &legalFor(bool Pred, std::initializer_list<LLT> Types) {
609 if (!Pred)
610 return *this;
611 return actionFor(LegalizeAction::Legal, Types);
612 }
613 /// The instruction is legal when type indexes 0 and 1 is any type pair in the
614 /// given list.
615 LegalizeRuleSet &legalFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
616 return actionFor(LegalizeAction::Legal, Types);
617 }
619 std::initializer_list<std::pair<LLT, LLT>> Types) {
620 if (!Pred)
621 return *this;
622 return actionFor(LegalizeAction::Legal, Types);
623 }
625 legalFor(bool Pred, std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
626 if (!Pred)
627 return *this;
628 return actionFor(LegalizeAction::Legal, Types);
629 }
630 /// The instruction is legal when type index 0 is any type in the given list
631 /// and imm index 0 is anything.
632 LegalizeRuleSet &legalForTypeWithAnyImm(std::initializer_list<LLT> Types) {
633 markAllIdxsAsCovered();
634 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
635 }
636
638 std::initializer_list<std::pair<LLT, LLT>> Types) {
639 markAllIdxsAsCovered();
640 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
641 }
642
643 /// The instruction is legal when type indexes 0 and 1 along with the memory
644 /// size and minimum alignment is any type and size tuple in the given list.
646 std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
647 TypesAndMemDesc) {
648 return actionIf(LegalizeAction::Legal,
650 typeIdx(0), typeIdx(1), /*MMOIdx*/ 0, TypesAndMemDesc));
651 }
653 bool Pred, std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
654 TypesAndMemDesc) {
655 if (!Pred)
656 return *this;
657 return actionIf(LegalizeAction::Legal,
659 typeIdx(0), typeIdx(1), /*MMOIdx=*/0, TypesAndMemDesc));
660 }
661 /// The instruction is legal when type indexes 0 and 1 are both in the given
662 /// list. That is, the type pair is in the cartesian product of the list.
663 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types) {
664 return actionForCartesianProduct(LegalizeAction::Legal, Types);
665 }
666 /// The instruction is legal when type indexes 0 and 1 are both their
667 /// respective lists.
668 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
669 std::initializer_list<LLT> Types1) {
670 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
671 }
672 /// The instruction is legal when type indexes 0, 1, and 2 are both their
673 /// respective lists.
674 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
675 std::initializer_list<LLT> Types1,
676 std::initializer_list<LLT> Types2) {
677 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1,
678 Types2);
679 }
680
682 using namespace LegalizeMutations;
683 markAllIdxsAsCovered();
684 return actionIf(LegalizeAction::Legal, always);
685 }
686
687 /// The specified type index is coerced if predicate is true.
690 // We have no choice but conservatively assume that lowering with a
691 // free-form user provided Predicate properly handles all type indices:
692 markAllIdxsAsCovered();
693 return actionIf(LegalizeAction::Bitcast, Predicate, Mutation);
694 }
695
696 /// The instruction is lowered.
698 using namespace LegalizeMutations;
699 // We have no choice but conservatively assume that predicate-less lowering
700 // properly handles all type indices by design:
701 markAllIdxsAsCovered();
702 return actionIf(LegalizeAction::Lower, always);
703 }
704 /// The instruction is lowered if predicate is true. Keep type index 0 as the
705 /// same type.
707 using namespace LegalizeMutations;
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);
712 }
713 /// The instruction is lowered if predicate is true.
716 // We have no choice but conservatively assume that lowering with a
717 // free-form user provided Predicate properly handles all type indices:
718 markAllIdxsAsCovered();
719 return actionIf(LegalizeAction::Lower, Predicate, Mutation);
720 }
721 /// The instruction is lowered when type index 0 is any type in the given
722 /// list. Keep type index 0 as the same type.
723 LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types) {
724 return actionFor(LegalizeAction::Lower, Types);
725 }
726 /// The instruction is lowered when type index 0 is any type in the given
727 /// list.
728 LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types,
730 return actionFor(LegalizeAction::Lower, Types, Mutation);
731 }
732 /// The instruction is lowered when type indexes 0 and 1 is any type pair in
733 /// the given list. Keep type index 0 as the same type.
734 LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
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, provided Predicate pred is true.
740 std::initializer_list<std::pair<LLT, LLT>> Types) {
741 if (!Pred)
742 return *this;
743 return actionFor(LegalizeAction::Lower, Types);
744 }
745 /// The instruction is lowered when type indexes 0 and 1 is any type pair in
746 /// the given list.
747 LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types,
749 return actionFor(LegalizeAction::Lower, Types, Mutation);
750 }
751 /// The instruction is lowered when type indexes 0 and 1 are both in their
752 /// respective lists.
753 LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
754 std::initializer_list<LLT> Types1) {
755 using namespace LegalityPredicates;
756 return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1);
757 }
758 /// The instruction is lowered when type indexes 0, 1, and 2 are all in
759 /// their respective lists.
760 LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
761 std::initializer_list<LLT> Types1,
762 std::initializer_list<LLT> Types2) {
763 using namespace LegalityPredicates;
764 return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1,
765 Types2);
766 }
767
768 /// The instruction is emitted as a library call.
770 using namespace LegalizeMutations;
771 // We have no choice but conservatively assume that predicate-less lowering
772 // properly handles all type indices by design:
773 markAllIdxsAsCovered();
774 return actionIf(LegalizeAction::Libcall, always);
775 }
776
777 /// Like legalIf, but for the Libcall action.
779 // We have no choice but conservatively assume that a libcall with a
780 // free-form user provided Predicate properly handles all type indices:
781 markAllIdxsAsCovered();
782 return actionIf(LegalizeAction::Libcall, Predicate);
783 }
784 LegalizeRuleSet &libcallFor(std::initializer_list<LLT> Types) {
785 return actionFor(LegalizeAction::Libcall, Types);
786 }
787 LegalizeRuleSet &libcallFor(bool Pred, std::initializer_list<LLT> Types) {
788 if (!Pred)
789 return *this;
790 return actionFor(LegalizeAction::Libcall, Types);
791 }
793 libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
794 return actionFor(LegalizeAction::Libcall, Types);
795 }
797 libcallFor(bool Pred, std::initializer_list<std::pair<LLT, LLT>> Types) {
798 if (!Pred)
799 return *this;
800 return actionFor(LegalizeAction::Libcall, Types);
801 }
803 libcallForCartesianProduct(std::initializer_list<LLT> Types) {
804 return actionForCartesianProduct(LegalizeAction::Libcall, Types);
805 }
807 libcallForCartesianProduct(std::initializer_list<LLT> Types0,
808 std::initializer_list<LLT> Types1) {
809 return actionForCartesianProduct(LegalizeAction::Libcall, Types0, Types1);
810 }
811
812 /// Widen the scalar to the one selected by the mutation if the predicate is
813 /// true.
816 // We have no choice but conservatively assume that an action with a
817 // free-form user provided Predicate properly handles all type indices:
818 markAllIdxsAsCovered();
819 return actionIf(LegalizeAction::WidenScalar, Predicate, Mutation);
820 }
821 /// Widen the scalar, specified in mutation, when type index 0 is any type in
822 /// the given list.
823 LegalizeRuleSet &widenScalarFor(std::initializer_list<LLT> Types,
825 return actionFor(LegalizeAction::WidenScalar, Types, Mutation);
826 }
827 /// Widen the scalar, specified in mutation, when type indexes 0 and 1 is any
828 /// type pair in the given list.
830 widenScalarFor(std::initializer_list<std::pair<LLT, LLT>> Types,
832 return actionFor(LegalizeAction::WidenScalar, Types, Mutation);
833 }
834
835 /// Narrow the scalar to the one selected by the mutation if the predicate is
836 /// true.
839 // We have no choice but conservatively assume that an action with a
840 // free-form user provided Predicate properly handles all type indices:
841 markAllIdxsAsCovered();
842 return actionIf(LegalizeAction::NarrowScalar, Predicate, Mutation);
843 }
844 /// Narrow the scalar, specified in mutation, when type indexes 0 and 1 is any
845 /// type pair in the given list.
847 narrowScalarFor(std::initializer_list<std::pair<LLT, LLT>> Types,
849 return actionFor(LegalizeAction::NarrowScalar, Types, Mutation);
850 }
851
852 /// Add more elements to reach the type selected by the mutation if the
853 /// predicate is true.
856 // We have no choice but conservatively assume that an action with a
857 // free-form user provided Predicate properly handles all type indices:
858 markAllIdxsAsCovered();
859 return actionIf(LegalizeAction::MoreElements, Predicate, Mutation);
860 }
861 /// Remove elements to reach the type selected by the mutation if the
862 /// predicate is true.
865 // We have no choice but conservatively assume that an action with a
866 // free-form user provided Predicate properly handles all type indices:
867 markAllIdxsAsCovered();
868 return actionIf(LegalizeAction::FewerElements, Predicate, Mutation);
869 }
870
871 /// The instruction is unsupported.
873 markAllIdxsAsCovered();
874 return actionIf(LegalizeAction::Unsupported, always);
875 }
877 return actionIf(LegalizeAction::Unsupported, Predicate);
878 }
879
880 LegalizeRuleSet &unsupportedFor(std::initializer_list<LLT> Types) {
881 return actionFor(LegalizeAction::Unsupported, Types);
882 }
883
885 return actionIf(LegalizeAction::Unsupported,
887 }
888
889 /// Lower a memory operation if the memory size, rounded to bytes, is not a
890 /// power of 2. For example, this will not trigger for s1 or s7, but will for
891 /// s24.
893 return actionIf(LegalizeAction::Lower,
895 }
896
897 /// Lower a memory operation if the memory access size is not a round power of
898 /// 2 byte size. This is stricter than lowerIfMemSizeNotPow2, and more likely
899 /// what you want (e.g. this will lower s1, s7 and s24).
901 return actionIf(LegalizeAction::Lower,
903 }
904
906 // We have no choice but conservatively assume that a custom action with a
907 // free-form user provided Predicate properly handles all type indices:
908 markAllIdxsAsCovered();
909 return actionIf(LegalizeAction::Custom, Predicate);
910 }
911 LegalizeRuleSet &customFor(std::initializer_list<LLT> Types) {
912 return actionFor(LegalizeAction::Custom, Types);
913 }
914 LegalizeRuleSet &customFor(bool Pred, std::initializer_list<LLT> Types) {
915 if (!Pred)
916 return *this;
917 return actionFor(LegalizeAction::Custom, Types);
918 }
919
920 /// The instruction is custom when type indexes 0 and 1 is any type pair in
921 /// the given list.
922 LegalizeRuleSet &customFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
923 return actionFor(LegalizeAction::Custom, Types);
924 }
926 std::initializer_list<std::pair<LLT, LLT>> Types) {
927 if (!Pred)
928 return *this;
929 return actionFor(LegalizeAction::Custom, Types);
930 }
931
932 LegalizeRuleSet &customForCartesianProduct(std::initializer_list<LLT> Types) {
933 return actionForCartesianProduct(LegalizeAction::Custom, Types);
934 }
935 /// The instruction is custom when type indexes 0 and 1 are both in their
936 /// respective lists.
938 customForCartesianProduct(std::initializer_list<LLT> Types0,
939 std::initializer_list<LLT> Types1) {
940 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
941 }
942 /// The instruction is custom when type indexes 0, 1, and 2 are all in
943 /// their respective lists.
945 customForCartesianProduct(std::initializer_list<LLT> Types0,
946 std::initializer_list<LLT> Types1,
947 std::initializer_list<LLT> Types2) {
948 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1,
949 Types2);
950 }
951
952 /// The instruction is custom when the predicate is true and type indexes 0
953 /// and 1 are all in their respective lists.
955 customForCartesianProduct(bool Pred, std::initializer_list<LLT> Types0,
956 std::initializer_list<LLT> Types1) {
957 if (!Pred)
958 return *this;
959 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
960 }
961
962 /// Unconditionally custom lower.
964 return customIf(always);
965 }
966
967 /// Widen the scalar to the next power of two that is at least MinSize.
968 /// No effect if the type is a power of two, except if the type is smaller
969 /// than MinSize, or if the type is a vector type.
971 unsigned MinSize = 0) {
972 using namespace LegalityPredicates;
973 return actionIf(
974 LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
976 }
977
978 /// Widen the scalar to the next multiple of Size. No effect if the
979 /// type is not a scalar or is a multiple of Size.
981 unsigned Size) {
982 using namespace LegalityPredicates;
983 return actionIf(
984 LegalizeAction::WidenScalar, sizeNotMultipleOf(typeIdx(TypeIdx), Size),
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, scalarOrEltSizeNotPow2(typeIdx(TypeIdx)),
996 }
997
998 /// Widen the scalar or vector element type to the next power of two that is
999 /// at least MinSize. No effect if the scalar size is a power of two.
1001 unsigned MinSize = 0) {
1002 using namespace LegalityPredicates;
1003 return actionIf(
1004 LegalizeAction::WidenScalar,
1005 any(scalarOrEltNarrowerThan(TypeIdx, MinSize),
1006 scalarOrEltSizeNotPow2(typeIdx(TypeIdx))),
1008 }
1009
1011 using namespace LegalityPredicates;
1012 return actionIf(LegalizeAction::NarrowScalar, isScalar(typeIdx(TypeIdx)),
1013 Mutation);
1014 }
1015
1016 LegalizeRuleSet &scalarize(unsigned TypeIdx) {
1017 using namespace LegalityPredicates;
1018 return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)),
1020 }
1021
1023 using namespace LegalityPredicates;
1024 return actionIf(LegalizeAction::FewerElements,
1025 all(Predicate, isVector(typeIdx(TypeIdx))),
1027 }
1028
1029 /// Ensure the scalar or element is at least as wide as Ty.
1030 LegalizeRuleSet &minScalarOrElt(unsigned TypeIdx, const LLT Ty) {
1031 using namespace LegalityPredicates;
1032 using namespace LegalizeMutations;
1033 return actionIf(LegalizeAction::WidenScalar,
1034 scalarOrEltNarrowerThan(TypeIdx, Ty.getScalarSizeInBits()),
1035 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1036 }
1037
1038 /// Ensure the scalar or element is at least as wide as Ty.
1040 unsigned TypeIdx, const LLT Ty) {
1041 using namespace LegalityPredicates;
1042 using namespace LegalizeMutations;
1043 return actionIf(LegalizeAction::WidenScalar,
1044 all(Predicate, scalarOrEltNarrowerThan(
1045 TypeIdx, Ty.getScalarSizeInBits())),
1046 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1047 }
1048
1049 /// Ensure the vector size is at least as wide as VectorSize by promoting the
1050 /// element.
1052 unsigned VectorSize) {
1053 using namespace LegalityPredicates;
1054 using namespace LegalizeMutations;
1055 return actionIf(
1056 LegalizeAction::WidenScalar,
1057 [=](const LegalityQuery &Query) {
1058 const LLT VecTy = Query.Types[TypeIdx];
1059 return VecTy.isFixedVector() && VecTy.getSizeInBits() < VectorSize;
1060 },
1061 [=](const LegalityQuery &Query) {
1062 const LLT VecTy = Query.Types[TypeIdx];
1063 unsigned NumElts = VecTy.getNumElements();
1064 unsigned MinSize = VectorSize / NumElts;
1065 LLT NewTy = LLT::fixed_vector(
1066 NumElts, VecTy.getElementType().changeElementSize(MinSize));
1067 return std::make_pair(TypeIdx, NewTy);
1068 });
1069 }
1070
1071 /// Ensure the scalar is at least as wide as Ty.
1072 LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT Ty) {
1073 using namespace LegalityPredicates;
1074 using namespace LegalizeMutations;
1075 return actionIf(LegalizeAction::WidenScalar,
1076 scalarNarrowerThan(TypeIdx, Ty.getSizeInBits()),
1077 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1078 }
1079 LegalizeRuleSet &minScalar(bool Pred, unsigned TypeIdx, const LLT Ty) {
1080 if (!Pred)
1081 return *this;
1082 return minScalar(TypeIdx, Ty);
1083 }
1084
1085 /// Ensure the scalar is at least as wide as Ty if condition is met.
1087 const LLT Ty) {
1088 using namespace LegalityPredicates;
1089 using namespace LegalizeMutations;
1090 return actionIf(
1091 LegalizeAction::WidenScalar,
1092 [=](const LegalityQuery &Query) {
1093 const LLT QueryTy = Query.Types[TypeIdx];
1094 return QueryTy.isScalar() &&
1095 QueryTy.getSizeInBits() < Ty.getSizeInBits() &&
1096 Predicate(Query);
1097 },
1098 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1099 }
1100
1101 /// Ensure the scalar is at most as wide as Ty.
1102 LegalizeRuleSet &maxScalarOrElt(unsigned TypeIdx, const LLT Ty) {
1103 using namespace LegalityPredicates;
1104 using namespace LegalizeMutations;
1105 return actionIf(LegalizeAction::NarrowScalar,
1106 scalarOrEltWiderThan(TypeIdx, Ty.getScalarSizeInBits()),
1107 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1108 }
1109
1110 /// Ensure the scalar is at most as wide as Ty.
1111 LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT Ty) {
1112 using namespace LegalityPredicates;
1113 using namespace LegalizeMutations;
1114 return actionIf(LegalizeAction::NarrowScalar,
1115 scalarWiderThan(TypeIdx, Ty.getSizeInBits()),
1116 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1117 }
1118
1119 /// Conditionally limit the maximum size of the scalar.
1120 /// For example, when the maximum size of one type depends on the size of
1121 /// another such as extracting N bits from an M bit container.
1123 const LLT Ty) {
1124 using namespace LegalityPredicates;
1125 using namespace LegalizeMutations;
1126 return actionIf(
1127 LegalizeAction::NarrowScalar,
1128 [=](const LegalityQuery &Query) {
1129 const LLT QueryTy = Query.Types[TypeIdx];
1130 return QueryTy.isScalar() &&
1131 QueryTy.getSizeInBits() > Ty.getSizeInBits() &&
1132 Predicate(Query);
1133 },
1134 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1135 }
1136
1137 /// Limit the range of scalar sizes to MinTy and MaxTy.
1138 LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT MinTy,
1139 const LLT MaxTy) {
1140 assert(MinTy.isScalar() && MaxTy.isScalar() && "Expected scalar types");
1141 return minScalar(TypeIdx, MinTy).maxScalar(TypeIdx, MaxTy);
1142 }
1143
1144 LegalizeRuleSet &clampScalar(bool Pred, unsigned TypeIdx, const LLT MinTy,
1145 const LLT MaxTy) {
1146 if (!Pred)
1147 return *this;
1148 return clampScalar(TypeIdx, MinTy, MaxTy);
1149 }
1150
1151 /// Limit the range of scalar sizes to MinTy and MaxTy.
1152 LegalizeRuleSet &clampScalarOrElt(unsigned TypeIdx, const LLT MinTy,
1153 const LLT MaxTy) {
1154 return minScalarOrElt(TypeIdx, MinTy).maxScalarOrElt(TypeIdx, MaxTy);
1155 }
1156
1157 /// Widen the scalar to match the size of another.
1158 LegalizeRuleSet &minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx) {
1159 typeIdx(TypeIdx);
1160 return actionIf(
1161 LegalizeAction::WidenScalar,
1162 [=](const LegalityQuery &Query) {
1163 return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
1164 Query.Types[TypeIdx].getSizeInBits();
1165 },
1166 LegalizeMutations::changeElementSizeTo(TypeIdx, LargeTypeIdx));
1167 }
1168
1169 /// Narrow the scalar to match the size of another.
1170 LegalizeRuleSet &maxScalarSameAs(unsigned TypeIdx, unsigned NarrowTypeIdx) {
1171 typeIdx(TypeIdx);
1172 return actionIf(
1173 LegalizeAction::NarrowScalar,
1174 [=](const LegalityQuery &Query) {
1175 return Query.Types[NarrowTypeIdx].getScalarSizeInBits() <
1176 Query.Types[TypeIdx].getSizeInBits();
1177 },
1178 LegalizeMutations::changeElementSizeTo(TypeIdx, NarrowTypeIdx));
1179 }
1180
1181 /// Change the type \p TypeIdx to have the same scalar size as type \p
1182 /// SameSizeIdx.
1183 LegalizeRuleSet &scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx) {
1184 return minScalarSameAs(TypeIdx, SameSizeIdx)
1185 .maxScalarSameAs(TypeIdx, SameSizeIdx);
1186 }
1187
1188 /// Conditionally widen the scalar or elt to match the size of another.
1190 unsigned TypeIdx, unsigned LargeTypeIdx) {
1191 typeIdx(TypeIdx);
1192 return widenScalarIf(
1193 [=](const LegalityQuery &Query) {
1194 return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
1195 Query.Types[TypeIdx].getScalarSizeInBits() &&
1196 Predicate(Query);
1197 },
1198 [=](const LegalityQuery &Query) {
1199 LLT T = Query.Types[TypeIdx].changeElementSize(
1200 Query.Types[LargeTypeIdx].getScalarSizeInBits());
1201 return std::make_pair(TypeIdx, T);
1202 });
1203 }
1204
1205 /// Conditionally narrow the scalar or elt to match the size of another.
1207 unsigned TypeIdx,
1208 unsigned SmallTypeIdx) {
1209 typeIdx(TypeIdx);
1210 return narrowScalarIf(
1211 [=](const LegalityQuery &Query) {
1212 return Query.Types[SmallTypeIdx].getScalarSizeInBits() <
1213 Query.Types[TypeIdx].getScalarSizeInBits() &&
1214 Predicate(Query);
1215 },
1216 [=](const LegalityQuery &Query) {
1217 LLT T = Query.Types[SmallTypeIdx];
1218 return std::make_pair(TypeIdx, T);
1219 });
1220 }
1221
1222 /// Add more elements to the vector to reach the next power of two.
1223 /// No effect if the type is not a vector or the element count is a power of
1224 /// two.
1226 using namespace LegalityPredicates;
1227 return actionIf(LegalizeAction::MoreElements,
1228 numElementsNotPow2(typeIdx(TypeIdx)),
1230 }
1231
1232 /// Limit the number of elements in EltTy vectors to at least MinElements.
1233 LegalizeRuleSet &clampMinNumElements(unsigned TypeIdx, const LLT EltTy,
1234 unsigned MinElements) {
1235 // Mark the type index as covered:
1236 typeIdx(TypeIdx);
1237 return actionIf(
1238 LegalizeAction::MoreElements,
1239 [=](const LegalityQuery &Query) {
1240 LLT VecTy = Query.Types[TypeIdx];
1241 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1242 VecTy.getNumElements() < MinElements;
1243 },
1244 [=](const LegalityQuery &Query) {
1245 LLT VecTy = Query.Types[TypeIdx];
1246 return std::make_pair(
1247 TypeIdx, LLT::fixed_vector(MinElements, VecTy.getElementType()));
1248 });
1249 }
1250
1251 /// Set number of elements to nearest larger multiple of NumElts.
1252 LegalizeRuleSet &alignNumElementsTo(unsigned TypeIdx, const LLT EltTy,
1253 unsigned NumElts) {
1254 typeIdx(TypeIdx);
1255 return actionIf(
1256 LegalizeAction::MoreElements,
1257 [=](const LegalityQuery &Query) {
1258 LLT VecTy = Query.Types[TypeIdx];
1259 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1260 (VecTy.getNumElements() % NumElts != 0);
1261 },
1262 [=](const LegalityQuery &Query) {
1263 LLT VecTy = Query.Types[TypeIdx];
1264 unsigned NewSize = alignTo(VecTy.getNumElements(), NumElts);
1265 return std::make_pair(
1266 TypeIdx, LLT::fixed_vector(NewSize, VecTy.getElementType()));
1267 });
1268 }
1269
1270 /// Limit the number of elements in EltTy vectors to at most MaxElements.
1271 LegalizeRuleSet &clampMaxNumElements(unsigned TypeIdx, const LLT EltTy,
1272 unsigned MaxElements) {
1273 // Mark the type index as covered:
1274 typeIdx(TypeIdx);
1275 return actionIf(
1276 LegalizeAction::FewerElements,
1277 [=](const LegalityQuery &Query) {
1278 LLT VecTy = Query.Types[TypeIdx];
1279 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1280 VecTy.getNumElements() > MaxElements;
1281 },
1282 [=](const LegalityQuery &Query) {
1283 LLT VecTy = Query.Types[TypeIdx];
1284 LLT NewTy = LLT::scalarOrVector(ElementCount::getFixed(MaxElements),
1285 VecTy.getElementType());
1286 return std::make_pair(TypeIdx, NewTy);
1287 });
1288 }
1289 /// Limit the number of elements for the given vectors to at least MinTy's
1290 /// number of elements and at most MaxTy's number of elements.
1291 ///
1292 /// No effect if the type is not a vector or does not have the same element
1293 /// type as the constraints.
1294 /// The element type of MinTy and MaxTy must match.
1295 LegalizeRuleSet &clampNumElements(unsigned TypeIdx, const LLT MinTy,
1296 const LLT MaxTy) {
1297 assert(MinTy.getElementType() == MaxTy.getElementType() &&
1298 "Expected element types to agree");
1299
1300 assert((!MinTy.isScalableVector() && !MaxTy.isScalableVector()) &&
1301 "Unexpected scalable vectors");
1302
1303 const LLT EltTy = MinTy.getElementType();
1304 return clampMinNumElements(TypeIdx, EltTy, MinTy.getNumElements())
1305 .clampMaxNumElements(TypeIdx, EltTy, MaxTy.getNumElements());
1306 }
1307
1308 /// Express \p EltTy vectors strictly using vectors with \p NumElts elements
1309 /// (or scalars when \p NumElts equals 1).
1310 /// First pad with undef elements to nearest larger multiple of \p NumElts.
1311 /// Then perform split with all sub-instructions having the same type.
1312 /// Using clampMaxNumElements (non-strict) can result in leftover instruction
1313 /// with different type (fewer elements then \p NumElts or scalar).
1314 /// No effect if the type is not a vector.
1315 LegalizeRuleSet &clampMaxNumElementsStrict(unsigned TypeIdx, const LLT EltTy,
1316 unsigned NumElts) {
1317 return alignNumElementsTo(TypeIdx, EltTy, NumElts)
1318 .clampMaxNumElements(TypeIdx, EltTy, NumElts);
1319 }
1320
1321 /// Check if there is no type index which is obviously not handled by the
1322 /// LegalizeRuleSet in any way at all.
1323 /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
1324 LLVM_ABI bool verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const;
1325 /// Check if there is no imm index which is obviously not handled by the
1326 /// LegalizeRuleSet in any way at all.
1327 /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
1328 LLVM_ABI bool verifyImmIdxsCoverage(unsigned NumImmIdxs) const;
1329
1330 /// Apply the ruleset to the given LegalityQuery.
1331 LLVM_ABI LegalizeActionStep apply(const LegalityQuery &Query) const;
1332};
1333
1335public:
1336 virtual ~LegalizerInfo() = default;
1337
1338 unsigned getOpcodeIdxForOpcode(unsigned Opcode) const;
1339 unsigned getActionDefinitionsIdx(unsigned Opcode) const;
1340
1341 /// Perform simple self-diagnostic and assert if there is anything obviously
1342 /// wrong with the actions set up.
1343 void verify(const MCInstrInfo &MII) const;
1344
1345 /// Get the action definitions for the given opcode. Use this to run a
1346 /// LegalityQuery through the definitions.
1347 const LegalizeRuleSet &getActionDefinitions(unsigned Opcode) const;
1348
1349 /// Get the action definition builder for the given opcode. Use this to define
1350 /// the action definitions.
1351 ///
1352 /// It is an error to request an opcode that has already been requested by the
1353 /// multiple-opcode variant.
1355
1356 /// Get the action definition builder for the given set of opcodes. Use this
1357 /// to define the action definitions for multiple opcodes at once. The first
1358 /// opcode given will be considered the representative opcode and will hold
1359 /// the definitions whereas the other opcodes will be configured to refer to
1360 /// the representative opcode. This lowers memory requirements and very
1361 /// slightly improves performance.
1362 ///
1363 /// It would be very easy to introduce unexpected side-effects as a result of
1364 /// this aliasing if it were permitted to request different but intersecting
1365 /// sets of opcodes but that is difficult to keep track of. It is therefore an
1366 /// error to request the same opcode twice using this API, to request an
1367 /// opcode that already has definitions, or to use the single-opcode API on an
1368 /// opcode that has already been requested by this API.
1370 getActionDefinitionsBuilder(std::initializer_list<unsigned> Opcodes);
1371 void aliasActionDefinitions(unsigned OpcodeTo, unsigned OpcodeFrom);
1372
1373 /// Determine what action should be taken to legalize the described
1374 /// instruction. Requires computeTables to have been called.
1375 ///
1376 /// \returns a description of the next legalization step to perform.
1377 LegalizeActionStep getAction(const LegalityQuery &Query) const;
1378
1379 /// Determine what action should be taken to legalize the given generic
1380 /// instruction.
1381 ///
1382 /// \returns a description of the next legalization step to perform.
1384 const MachineRegisterInfo &MRI) const;
1385
1386 bool isLegal(const LegalityQuery &Query) const {
1387 return getAction(Query).Action == LegalizeAction::Legal;
1388 }
1389
1390 bool isLegalOrCustom(const LegalityQuery &Query) const {
1391 auto Action = getAction(Query).Action;
1392 return Action == LegalizeAction::Legal || Action == LegalizeAction::Custom;
1393 }
1394
1395 bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
1396 bool isLegalOrCustom(const MachineInstr &MI,
1397 const MachineRegisterInfo &MRI) const;
1398
1399 /// Called for instructions with the Custom LegalizationAction.
1401 LostDebugLocObserver &LocObserver) const {
1402 llvm_unreachable("must implement this if custom action is used");
1403 }
1404
1405 /// \returns true if MI is either legal or has been legalized and false if not
1406 /// legal.
1407 /// Return true if MI is either legal or has been legalized and false
1408 /// if not legal.
1410 MachineInstr &MI) const {
1411 return true;
1412 }
1413
1414 /// Return the opcode (SEXT/ZEXT/ANYEXT) that should be performed while
1415 /// widening a constant of type SmallTy which targets can override.
1416 /// For eg, the DAG does (SmallTy.isByteSized() ? G_SEXT : G_ZEXT) which
1417 /// will be the default.
1418 virtual unsigned getExtOpcodeForWideningConstant(LLT SmallTy) const;
1419
1420private:
1421 static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
1422 static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
1423
1424 LegalizeRuleSet RulesForOpcode[LastOp - FirstOp + 1];
1425};
1426
1427#ifndef NDEBUG
1428/// Checks that MIR is fully legal, returns an illegal instruction if it's not,
1429/// nullptr otherwise
1430const MachineInstr *machineFunctionIsIllegal(const MachineFunction &MF);
1431#endif
1432
1433} // end namespace llvm.
1434
1435#endif // LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
uint64_t Imm
Atomic ordering constants.
#define LLVM_ABI
Definition Compiler.h:211
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
MachineRegisterInfo & MRI
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:306
constexpr bool isScalableVector() const
Returns true if the LLT is a scalable vector.
constexpr bool isScalar() const
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
static constexpr LLT scalarOrVector(ElementCount EC, LLT ScalarTy)
LLT changeElementSize(unsigned NewEltSize) const
If this type is a vector, return a vector with the same number of elements but the new element size.
LegalizeRuleSet & minScalar(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at least as wide as Ty.
LegalizeRuleSet & clampScalar(bool Pred, unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
LegalizeRuleSet & maxScalarSameAs(unsigned TypeIdx, unsigned NarrowTypeIdx)
Narrow the scalar to match the size of another.
LegalizeRuleSet & widenScalarOrEltToNextPow2OrMinSize(unsigned TypeIdx, unsigned MinSize=0)
Widen the scalar or vector element type to the next power of two that is at least MinSize.
LegalizeRuleSet & customForCartesianProduct(bool Pred, std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is custom when the predicate is true and type indexes 0 and 1 are all in their respec...
LegalizeRuleSet & legalFor(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list.
LegalizeRuleSet & lowerFor(bool Pred, std::initializer_list< std::pair< LLT, LLT > > Types)
The instruction is lowered when type indexes 0 and 1 is any type pair in the given list,...
LegalizeRuleSet & maxScalarEltSameAsIf(LegalityPredicate Predicate, unsigned TypeIdx, unsigned SmallTypeIdx)
Conditionally narrow the scalar or elt to match the size of another.
LegalizeRuleSet & unsupported()
The instruction is unsupported.
LegalizeRuleSet & legalFor(bool Pred, std::initializer_list< std::tuple< LLT, LLT, LLT > > Types)
LegalizeRuleSet & scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx)
Change the type TypeIdx to have the same scalar size as type SameSizeIdx.
LegalizeRuleSet & fewerElementsIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Remove elements to reach the type selected by the mutation if the predicate is true.
LegalizeRuleSet & clampScalarOrElt(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
void aliasTo(unsigned Opcode)
LegalizeRuleSet & bitcastIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
The specified type index is coerced if predicate is true.
LegalizeRuleSet & libcall()
The instruction is emitted as a library call.
LegalizeRuleSet & libcallFor(std::initializer_list< LLT > Types)
LLVM_ABI bool verifyImmIdxsCoverage(unsigned NumImmIdxs) const
Check if there is no imm index which is obviously not handled by the LegalizeRuleSet in any way at al...
LegalizeRuleSet & maxScalar(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at most as wide as Ty.
LegalizeRuleSet & minScalarOrElt(unsigned TypeIdx, const LLT Ty)
Ensure the scalar or element is at least as wide as Ty.
LegalizeRuleSet & clampMaxNumElements(unsigned TypeIdx, const LLT EltTy, unsigned MaxElements)
Limit the number of elements in EltTy vectors to at most MaxElements.
LegalizeRuleSet & clampMinNumElements(unsigned TypeIdx, const LLT EltTy, unsigned MinElements)
Limit the number of elements in EltTy vectors to at least MinElements.
LegalizeRuleSet & libcallForCartesianProduct(std::initializer_list< LLT > Types)
LegalizeRuleSet & unsupportedFor(std::initializer_list< LLT > Types)
LegalizeRuleSet & legalFor(bool Pred, std::initializer_list< LLT > Types)
LegalizeRuleSet & widenVectorEltsToVectorMinSize(unsigned TypeIdx, unsigned VectorSize)
Ensure the vector size is at least as wide as VectorSize by promoting the element.
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is legal when type indexes 0 and 1 are both their respective lists.
LegalizeRuleSet & lowerIfMemSizeNotPow2()
Lower a memory operation if the memory size, rounded to bytes, is not a power of 2.
LegalizeRuleSet & lowerFor(std::initializer_list< LLT > Types, LegalizeMutation Mutation)
The instruction is lowered when type index 0 is any type in the given list.
LegalizeRuleSet & minScalarEltSameAsIf(LegalityPredicate Predicate, unsigned TypeIdx, unsigned LargeTypeIdx)
Conditionally widen the scalar or elt to match the size of another.
LegalizeRuleSet & customForCartesianProduct(std::initializer_list< LLT > Types)
LegalizeRuleSet & lowerIfMemSizeNotByteSizePow2()
Lower a memory operation if the memory access size is not a round power of 2 byte size.
LegalizeRuleSet & widenScalarFor(std::initializer_list< LLT > Types, LegalizeMutation Mutation)
Widen the scalar, specified in mutation, when type index 0 is any type in the given list.
LegalizeRuleSet & minScalar(bool Pred, unsigned TypeIdx, const LLT Ty)
LegalizeRuleSet & moreElementsToNextPow2(unsigned TypeIdx)
Add more elements to the vector to reach the next power of two.
LegalizeRuleSet & customForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is custom when type indexes 0 and 1 are both in their respective lists.
LegalizeRuleSet & legalForTypeWithAnyImm(std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & lowerFor(std::initializer_list< std::pair< LLT, LLT > > Types)
The instruction is lowered when type indexes 0 and 1 is any type pair in the given list.
LegalizeRuleSet & narrowScalarIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Narrow the scalar to the one selected by the mutation if the predicate is true.
LegalizeRuleSet & lower()
The instruction is lowered.
LegalizeRuleSet & moreElementsIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Add more elements to reach the type selected by the mutation if the predicate is true.
LegalizeRuleSet & narrowScalarFor(std::initializer_list< std::pair< LLT, LLT > > Types, LegalizeMutation Mutation)
Narrow the scalar, specified in mutation, when type indexes 0 and 1 is any type pair in the given lis...
LegalizeRuleSet & narrowScalar(unsigned TypeIdx, LegalizeMutation Mutation)
LegalizeRuleSet & customFor(bool Pred, std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & lowerFor(std::initializer_list< LLT > Types)
The instruction is lowered when type index 0 is any type in the given list.
LegalizeRuleSet & scalarizeIf(LegalityPredicate Predicate, unsigned TypeIdx)
LegalizeRuleSet & lowerIf(LegalityPredicate Predicate)
The instruction is lowered if predicate is true.
LegalizeRuleSet & clampScalar(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1, std::initializer_list< LLT > Types2)
The instruction is legal when type indexes 0, 1, and 2 are both their respective lists.
LegalizeRuleSet & alignNumElementsTo(unsigned TypeIdx, const LLT EltTy, unsigned NumElts)
Set number of elements to nearest larger multiple of NumElts.
LegalizeRuleSet & custom()
Unconditionally custom lower.
LegalizeRuleSet & widenScalarFor(std::initializer_list< std::pair< LLT, LLT > > Types, LegalizeMutation Mutation)
Widen the scalar, specified in mutation, when type indexes 0 and 1 is any type pair in the given list...
LegalizeRuleSet & libcallForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
LegalizeRuleSet & clampMaxNumElementsStrict(unsigned TypeIdx, const LLT EltTy, unsigned NumElts)
Express EltTy vectors strictly using vectors with NumElts elements (or scalars when NumElts equals 1)...
LegalizeRuleSet & minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx)
Widen the scalar to match the size of another.
LegalizeRuleSet & unsupportedIf(LegalityPredicate Predicate)
LegalizeRuleSet & minScalarOrEltIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT Ty)
Ensure the scalar or element is at least as wide as Ty.
LegalizeRuleSet & widenScalarIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Widen the scalar to the one selected by the mutation if the predicate is true.
LegalizeRuleSet & libcallFor(std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & customFor(bool Pred, std::initializer_list< LLT > Types)
LegalizeRuleSet & legalForTypeWithAnyImm(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list and imm index 0 is anything.
LegalizeRuleSet & lowerForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1, std::initializer_list< LLT > Types2)
The instruction is lowered when type indexes 0, 1, and 2 are all in their respective lists.
LegalizeRuleSet & legalForTypesWithMemDesc(bool Pred, std::initializer_list< LegalityPredicates::TypePairAndMemDesc > TypesAndMemDesc)
LegalizeRuleSet & legalFor(std::initializer_list< std::pair< LLT, LLT > > Types)
The instruction is legal when type indexes 0 and 1 is any type pair in the given list.
LegalizeRuleSet & libcallFor(bool Pred, std::initializer_list< LLT > Types)
LegalizeRuleSet & libcallFor(bool Pred, std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & alwaysLegal()
LegalizeRuleSet & legalFor(bool Pred, std::initializer_list< std::pair< LLT, LLT > > Types)
unsigned getAlias() const
LegalizeRuleSet & clampNumElements(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the number of elements for the given vectors to at least MinTy's number of elements and at most...
LegalizeRuleSet & unsupportedIfMemSizeNotPow2()
LegalizeRuleSet & maxScalarIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT Ty)
Conditionally limit the maximum size of the scalar.
LegalizeRuleSet & customIf(LegalityPredicate Predicate)
LegalizeRuleSet & customForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1, std::initializer_list< LLT > Types2)
The instruction is custom when type indexes 0, 1, and 2 are all in their respective lists.
LegalizeRuleSet & widenScalarToNextPow2(unsigned TypeIdx, unsigned MinSize=0)
Widen the scalar to the next power of two that is at least MinSize.
LegalizeRuleSet & scalarize(unsigned TypeIdx)
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types)
The instruction is legal when type indexes 0 and 1 are both in the given list.
LegalizeRuleSet & lowerForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is lowered when type indexes 0 and 1 are both in their respective lists.
LegalizeRuleSet & lowerIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
The instruction is lowered if predicate is true.
LegalizeRuleSet & legalForTypesWithMemDesc(std::initializer_list< LegalityPredicates::TypePairAndMemDesc > TypesAndMemDesc)
The instruction is legal when type indexes 0 and 1 along with the memory size and minimum alignment i...
LegalizeRuleSet & libcallIf(LegalityPredicate Predicate)
Like legalIf, but for the Libcall action.
LegalizeRuleSet & maxScalarOrElt(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at most as wide as Ty.
LegalizeRuleSet & customFor(std::initializer_list< std::pair< LLT, LLT > > Types)
The instruction is custom when type indexes 0 and 1 is any type pair in the given list.
LegalizeRuleSet & minScalarIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at least as wide as Ty if condition is met.
unsigned immIdx(unsigned ImmIdx)
LLVM_ABI bool verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const
Check if there is no type index which is obviously not handled by the LegalizeRuleSet in any way at a...
LegalizeRuleSet & widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned MinSize=0)
Widen the scalar or vector element type to the next power of two that is at least MinSize.
LLVM_ABI LegalizeActionStep apply(const LegalityQuery &Query) const
Apply the ruleset to the given LegalityQuery.
LegalizeRuleSet & lowerFor(std::initializer_list< std::pair< LLT, LLT > > Types, LegalizeMutation Mutation)
The instruction is lowered when type indexes 0 and 1 is any type pair in the given list.
LegalizeRuleSet & legalIf(LegalityPredicate Predicate)
The instruction is legal if predicate is true.
LegalizeRuleSet & customFor(std::initializer_list< LLT > Types)
LegalizeRuleSet & widenScalarToNextMultipleOf(unsigned TypeIdx, unsigned Size)
Widen the scalar to the next multiple of Size.
A single rule in a legalizer info ruleset.
std::pair< unsigned, LLT > determineMutation(const LegalityQuery &Query) const
Determine the change to make.
bool match(const LegalityQuery &Query) const
Test whether the LegalityQuery matches.
LegalizeRule(LegalityPredicate Predicate, LegalizeAction Action, LegalizeMutation Mutation=nullptr)
LegalizeAction getAction() const
const LegalizeRuleSet & getActionDefinitions(unsigned Opcode) const
Get the action definitions for the given opcode.
virtual ~LegalizerInfo()=default
LegalizeRuleSet & getActionDefinitionsBuilder(unsigned Opcode)
Get the action definition builder for the given opcode.
bool isLegalOrCustom(const LegalityQuery &Query) const
void aliasActionDefinitions(unsigned OpcodeTo, unsigned OpcodeFrom)
virtual bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI, LostDebugLocObserver &LocObserver) const
Called for instructions with the Custom LegalizationAction.
unsigned getOpcodeIdxForOpcode(unsigned Opcode) const
bool isLegal(const LegalityQuery &Query) const
unsigned getActionDefinitionsIdx(unsigned Opcode) const
virtual bool legalizeIntrinsic(LegalizerHelper &Helper, MachineInstr &MI) const
LegalizeActionStep getAction(const LegalityQuery &Query) const
Determine what action should be taken to legalize the described instruction.
Interface to description of machine instruction set.
Definition MCInstrInfo.h:27
Representation of each machine instruction.
A description of a memory reference used in the backend.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI LegalityPredicate scalarOrEltWiderThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar or a vector with an element type that's wider than the ...
LLVM_ABI LegalityPredicate isScalar(unsigned TypeIdx)
True iff the specified type index is a scalar.
LLVM_ABI LegalityPredicate memSizeInBytesNotPow2(unsigned MMOIdx)
True iff the specified MMO index has a size (rounded to bytes) that is not a power of 2.
LLVM_ABI LegalityPredicate numElementsNotPow2(unsigned TypeIdx)
True iff the specified type index is a vector whose element count is not a power of 2.
LLVM_ABI LegalityPredicate isPointerVector(unsigned TypeIdx)
True iff the specified type index is a vector of pointers (with any address space).
LLVM_ABI LegalityPredicate isPointer(unsigned TypeIdx)
True iff the specified type index is a pointer (with any address space).
LLVM_ABI LegalityPredicate vectorElementCountIsLessThanOrEqualTo(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a vector with a number of elements that's less than or equal to ...
LLVM_ABI LegalityPredicate typeInSet(unsigned TypeIdx, std::initializer_list< LLT > TypesInit)
True iff the given type index is one of the specified types.
LLVM_ABI LegalityPredicate smallerThan(unsigned TypeIdx0, unsigned TypeIdx1)
True iff the first type index has a smaller total bit size than second type index.
LLVM_ABI LegalityPredicate immIs(unsigned ImmIdx, int64_t Imm)
True iff the immediate at the given index has the specified value.
LLVM_ABI LegalityPredicate atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx, AtomicOrdering Ordering)
True iff the specified MMO index has at an atomic ordering of at Ordering or stronger.
LLVM_ABI LegalityPredicate scalarOrEltSizeNotPow2(unsigned TypeIdx)
True iff the specified type index is a scalar or vector whose element size is not a power of 2.
LLVM_ABI LegalityPredicate largerThan(unsigned TypeIdx0, unsigned TypeIdx1)
True iff the first type index has a larger total bit size than second type index.
LLVM_ABI LegalityPredicate typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1, std::initializer_list< std::pair< LLT, LLT > > TypesInit)
True iff the given types for the given pair of type indexes is one of the specified type pairs.
LLVM_ABI LegalityPredicate vectorElementCountIsGreaterThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a vector with a number of elements that's greater than the given...
LLVM_ABI LegalityPredicate memSizeNotByteSizePow2(unsigned MMOIdx)
True iff the specified MMO index has a size that is not an even byte size, or that even byte size is ...
Predicate any(Predicate P0, Predicate P1)
True iff P0 or P1 are true.
LLVM_ABI LegalityPredicate elementTypeIs(unsigned TypeIdx, LLT EltTy)
True if the type index is a vector with element type EltTy.
LLVM_ABI LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1)
True iff the specified type indices are both the same bit size.
LLVM_ABI LegalityPredicate scalarOrEltNarrowerThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar or vector with an element type that's narrower than the...
LLVM_ABI LegalityPredicate immIsNot(unsigned ImmIdx, int64_t Imm)
True iff the immediate at the given index does not have the specified value.
LLVM_ABI LegalityPredicate sizeIs(unsigned TypeIdx, unsigned Size)
True if the total bitwidth of the specified type index is Size bits.
LegalityPredicate typeIsNot(unsigned TypeIdx, LLT Type)
True iff the given type index is not the specified type.
LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
LLVM_ABI LegalityPredicate sizeNotPow2(unsigned TypeIdx)
True iff the specified type index is a scalar whose size is not a power of.
LLVM_ABI LegalityPredicate typeTupleInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned Type2, std::initializer_list< std::tuple< LLT, LLT, LLT > > TypesInit)
True iff the given types for the given tuple of type indexes is one of the specified type tuple.
Predicate all(Predicate P0, Predicate P1)
True iff P0 and P1 are true.
LLVM_ABI LegalityPredicate typePairAndMemDescInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx, std::initializer_list< TypePairAndMemDesc > TypesAndMemDescInit)
True iff the given types for the given pair of type indexes is one of the specified type pairs.
LLVM_ABI LegalityPredicate sizeNotMultipleOf(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar whose size is not a multiple of Size.
LLVM_ABI LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit)
True iff the given type index is the specified type.
Predicate predNot(Predicate P)
True iff P is false.
LLVM_ABI LegalityPredicate scalarWiderThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar that's wider than the given size.
LLVM_ABI LegalityPredicate immInSet(unsigned ImmIdx, std::initializer_list< int64_t > ImmsInit)
True iff the immediate at the given index has one of the specified values.
LLVM_ABI LegalityPredicate scalarNarrowerThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar that's narrower than the given size.
@ FewerElements
The (vector) operation should be implemented by splitting it into sub-vectors where the operation is ...
@ Legal
The operation is expected to be selectable directly by the target, and no transformation is necessary...
@ Libcall
The operation should be implemented as a call to some kind of runtime support library.
@ Unsupported
This operation is completely unsupported on the target.
@ Lower
The operation itself must be expressed in terms of simpler actions on this target.
@ WidenScalar
The operation should be implemented in terms of a wider scalar base-type.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ NarrowScalar
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type.
@ Custom
The target wants to do something special with this combination of operand and type.
@ 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:79
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:149
const MachineInstr * machineFunctionIsIllegal(const MachineFunction &MF)
Checks that MIR is fully legal, returns an illegal instruction if it's not, nullptr otherwise.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Other
Any other memory.
Definition ModRef.h:68
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
bool operator==(const TypePairAndMemDesc &Other) const
bool isCompatible(const TypePairAndMemDesc &Other) const
MemDesc(const MachineMemOperand &MMO)
MemDesc(LLT MemoryTy, uint64_t AlignInBits, AtomicOrdering Ordering, AtomicOrdering FailureOrdering)
The LegalityQuery object bundles together all the information that's needed to decide whether a given...
ArrayRef< int64_t > Immediates
ArrayRef< MemDesc > MMODescrs
Operations which require memory can use this to place requirements on the memory type for each MMO.
constexpr LegalityQuery(unsigned Opcode, ArrayRef< LLT > Types, ArrayRef< MemDesc > MMODescrs={}, ArrayRef< int64_t > Immediates={})
ArrayRef< LLT > Types
LLVM_ABI raw_ostream & print(raw_ostream &OS) const
The result of a query.
LegalizeAction Action
The action to take or the final answer.
LLT NewType
If describing an action, the new type for TypeIdx. Otherwise LLT{}.
unsigned TypeIdx
If describing an action, the type index to change. Otherwise zero.
LegalizeActionStep(LegalizeAction Action, unsigned TypeIdx, const LLT NewType)
bool operator==(const LegalizeActionStep &RHS) const