LLVM 21.0.0git
LegalizerInfo.h
Go to the documentation of this file.
1//===- llvm/CodeGen/GlobalISel/LegalizerInfo.h ------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// Interface for Targets to specify which operations they can successfully
10/// select and how the others should be expanded most efficiently.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
15#define LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
16
23#include "llvm/MC/MCInstrDesc.h"
26#include <cassert>
27#include <cstdint>
28#include <tuple>
29#include <utility>
30
31namespace llvm {
32
33extern cl::opt<bool> DisableGISelLegalityCheck;
34
35class MachineFunction;
36class raw_ostream;
37class LegalizerHelper;
38class LostDebugLocObserver;
39class MachineInstr;
40class MachineRegisterInfo;
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 /// Fall back onto the old rules.
97 /// TODO: Remove this once we've migrated
99};
100} // end namespace LegalizeActions
102
104
105/// The LegalityQuery object bundles together all the information that's needed
106/// to decide whether a given operation is legal or not.
107/// For efficiency, it doesn't make a copy of Types so care must be taken not
108/// to free it before using the query.
110 unsigned Opcode;
112
113 struct MemDesc {
117
118 MemDesc() = default;
122 : MemDesc(MMO.getMemoryType(), MMO.getAlign().value() * 8,
123 MMO.getSuccessOrdering()) {}
124 };
125
126 /// Operations which require memory can use this to place requirements on the
127 /// memory type for each MMO.
129
133
134 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.
142 LegalizeAction Action;
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
148 LegalizeActionStep(LegalizeAction Action, unsigned TypeIdx,
149 const LLT NewType)
151
153 : TypeIdx(Step.TypeIdx), NewType(Step.NewType) {
154 switch (Step.Action) {
157 break;
160 break;
163 break;
166 break;
169 break;
172 break;
175 break;
178 break;
181 break;
184 break;
187 break;
188 }
189 }
190
191 bool operator==(const LegalizeActionStep &RHS) const {
192 return std::tie(Action, TypeIdx, NewType) ==
193 std::tie(RHS.Action, RHS.TypeIdx, RHS.NewType);
194 }
195};
196
197using LegalityPredicate = std::function<bool (const LegalityQuery &)>;
199 std::function<std::pair<unsigned, LLT>(const LegalityQuery &)>;
200
201namespace LegalityPredicates {
207
209 return Type0 == Other.Type0 && Type1 == Other.Type1 &&
210 Align == Other.Align && MemTy == Other.MemTy;
211 }
212
213 /// \returns true if this memory access is legal with for the access described
214 /// by \p Other (The alignment is sufficient for the size and result type).
216 return Type0 == Other.Type0 && Type1 == Other.Type1 &&
217 Align >= Other.Align &&
218 // FIXME: This perhaps should be stricter, but the current legality
219 // rules are written only considering the size.
220 MemTy.getSizeInBits() == Other.MemTy.getSizeInBits();
221 }
222};
223
224/// True iff P is false.
225template <typename Predicate> Predicate predNot(Predicate P) {
226 return [=](const LegalityQuery &Query) { return !P(Query); };
227}
228
229/// True iff P0 and P1 are true.
230template<typename Predicate>
232 return [=](const LegalityQuery &Query) {
233 return P0(Query) && P1(Query);
234 };
235}
236/// True iff all given predicates are true.
237template<typename Predicate, typename... Args>
239 return all(all(P0, P1), args...);
240}
241
242/// True iff P0 or P1 are true.
243template<typename Predicate>
245 return [=](const LegalityQuery &Query) {
246 return P0(Query) || P1(Query);
247 };
248}
249/// True iff any given predicates are true.
250template<typename Predicate, typename... Args>
252 return any(any(P0, P1), args...);
253}
254
255/// True iff the given type index is the specified type.
256LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit);
257/// True iff the given type index is one of the specified types.
258LegalityPredicate typeInSet(unsigned TypeIdx,
259 std::initializer_list<LLT> TypesInit);
260
261/// True iff the given type index is not the specified type.
262inline LegalityPredicate typeIsNot(unsigned TypeIdx, LLT Type) {
263 return [=](const LegalityQuery &Query) {
264 return Query.Types[TypeIdx] != Type;
265 };
266}
267
268/// True iff the given types for the given pair of type indexes is one of the
269/// specified type pairs.
271typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1,
272 std::initializer_list<std::pair<LLT, LLT>> TypesInit);
273/// True iff the given types for the given tuple of type indexes is one of the
274/// specified type tuple.
276typeTupleInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned Type2,
277 std::initializer_list<std::tuple<LLT, LLT, LLT>> TypesInit);
278/// True iff the given types for the given pair of type indexes is one of the
279/// specified type pairs.
281 unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx,
282 std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit);
283/// True iff the specified type index is a scalar.
284LegalityPredicate isScalar(unsigned TypeIdx);
285/// True iff the specified type index is a vector.
286LegalityPredicate isVector(unsigned TypeIdx);
287/// True iff the specified type index is a pointer (with any address space).
288LegalityPredicate isPointer(unsigned TypeIdx);
289/// True iff the specified type index is a pointer with the specified address
290/// space.
291LegalityPredicate isPointer(unsigned TypeIdx, unsigned AddrSpace);
292/// True iff the specified type index is a vector of pointers (with any address
293/// space).
294LegalityPredicate isPointerVector(unsigned TypeIdx);
295
296/// True if the type index is a vector with element type \p EltTy
297LegalityPredicate elementTypeIs(unsigned TypeIdx, LLT EltTy);
298
299/// True iff the specified type index is a scalar that's narrower than the given
300/// size.
301LegalityPredicate scalarNarrowerThan(unsigned TypeIdx, unsigned Size);
302
303/// True iff the specified type index is a scalar that's wider than the given
304/// size.
305LegalityPredicate scalarWiderThan(unsigned TypeIdx, unsigned Size);
306
307/// True iff the specified type index is a scalar or vector with an element type
308/// that's narrower than the given size.
309LegalityPredicate scalarOrEltNarrowerThan(unsigned TypeIdx, unsigned Size);
310
311/// True iff the specified type index is a scalar or a vector with an element
312/// type that's wider than the given size.
313LegalityPredicate scalarOrEltWiderThan(unsigned TypeIdx, unsigned Size);
314
315/// True iff the specified type index is a scalar whose size is not a multiple
316/// of Size.
317LegalityPredicate sizeNotMultipleOf(unsigned TypeIdx, unsigned Size);
318
319/// True iff the specified type index is a scalar whose size is not a power of
320/// 2.
321LegalityPredicate sizeNotPow2(unsigned TypeIdx);
322
323/// True iff the specified type index is a scalar or vector whose element size
324/// is not a power of 2.
326
327/// True if the total bitwidth of the specified type index is \p Size bits.
328LegalityPredicate sizeIs(unsigned TypeIdx, unsigned Size);
329
330/// True iff the specified type indices are both the same bit size.
331LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1);
332
333/// True iff the first type index has a larger total bit size than second type
334/// index.
335LegalityPredicate largerThan(unsigned TypeIdx0, unsigned TypeIdx1);
336
337/// True iff the first type index has a smaller total bit size than second type
338/// index.
339LegalityPredicate smallerThan(unsigned TypeIdx0, unsigned TypeIdx1);
340
341/// True iff the specified MMO index has a size (rounded to bytes) that is not a
342/// power of 2.
344
345/// True iff the specified MMO index has a size that is not an even byte size,
346/// or that even byte size is not a power of 2.
348
349/// True iff the specified type index is a vector whose element count is not a
350/// power of 2.
351LegalityPredicate numElementsNotPow2(unsigned TypeIdx);
352/// True iff the specified MMO index has at an atomic ordering of at Ordering or
353/// stronger.
355 AtomicOrdering Ordering);
356} // end namespace LegalityPredicates
357
358namespace LegalizeMutations {
359/// Select this specific type for the given type index.
360LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
361
362/// Keep the same type as the given type index.
363LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx);
364
365/// Keep the same scalar or element type as the given type index.
366LegalizeMutation changeElementTo(unsigned TypeIdx, unsigned FromTypeIdx);
367
368/// Keep the same scalar or element type as the given type.
369LegalizeMutation changeElementTo(unsigned TypeIdx, LLT Ty);
370
371/// Keep the same scalar or element type as \p TypeIdx, but take the number of
372/// elements from \p FromTypeIdx.
373LegalizeMutation changeElementCountTo(unsigned TypeIdx, unsigned FromTypeIdx);
374
375/// Keep the same scalar or element type as \p TypeIdx, but take the number of
376/// elements from \p Ty.
377LegalizeMutation changeElementCountTo(unsigned TypeIdx, LLT Ty);
378
379/// Change the scalar size or element size to have the same scalar size as type
380/// index \p FromIndex. Unlike changeElementTo, this discards pointer types and
381/// only changes the size.
382LegalizeMutation changeElementSizeTo(unsigned TypeIdx, unsigned FromTypeIdx);
383
384/// Widen the scalar type or vector element type for the given type index to the
385/// next power of 2.
386LegalizeMutation widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned Min = 0);
387
388/// Widen the scalar type or vector element type for the given type index to
389/// next multiple of \p Size.
391 unsigned Size);
392
393/// Add more elements to the type for the given type index to the next power of
394/// 2.
395LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min = 0);
396/// Break up the vector type for the given type index into the element type.
397LegalizeMutation scalarize(unsigned TypeIdx);
398} // end namespace LegalizeMutations
399
400/// A single rule in a legalizer info ruleset.
401/// The specified action is chosen when the predicate is true. Where appropriate
402/// for the action (e.g. for WidenScalar) the new type is selected using the
403/// given mutator.
406 LegalizeAction Action;
407 LegalizeMutation Mutation;
408
409public:
411 LegalizeMutation Mutation = nullptr)
412 : Predicate(Predicate), Action(Action), Mutation(Mutation) {}
413
414 /// Test whether the LegalityQuery matches.
415 bool match(const LegalityQuery &Query) const {
416 return Predicate(Query);
417 }
418
419 LegalizeAction getAction() const { return Action; }
420
421 /// Determine the change to make.
422 std::pair<unsigned, LLT> determineMutation(const LegalityQuery &Query) const {
423 if (Mutation)
424 return Mutation(Query);
425 return std::make_pair(0, LLT{});
426 }
427};
428
430 /// When non-zero, the opcode we are an alias of
431 unsigned AliasOf = 0;
432 /// If true, there is another opcode that aliases this one
433 bool IsAliasedByAnother = false;
435
436#ifndef NDEBUG
437 /// If bit I is set, this rule set contains a rule that may handle (predicate
438 /// or perform an action upon (or both)) the type index I. The uncertainty
439 /// comes from free-form rules executing user-provided lambda functions. We
440 /// conservatively assume such rules do the right thing and cover all type
441 /// indices. The bitset is intentionally 1 bit wider than it absolutely needs
442 /// to be to distinguish such cases from the cases where all type indices are
443 /// individually handled.
448#endif
449
450 unsigned typeIdx(unsigned TypeIdx) {
451 assert(TypeIdx <=
453 "Type Index is out of bounds");
454#ifndef NDEBUG
455 TypeIdxsCovered.set(TypeIdx);
456#endif
457 return TypeIdx;
458 }
459
460 void markAllIdxsAsCovered() {
461#ifndef NDEBUG
462 TypeIdxsCovered.set();
463 ImmIdxsCovered.set();
464#endif
465 }
466
467 void add(const LegalizeRule &Rule) {
468 assert(AliasOf == 0 &&
469 "RuleSet is aliased, change the representative opcode instead");
470 Rules.push_back(Rule);
471 }
472
473 static bool always(const LegalityQuery &) { return true; }
474
475 /// Use the given action when the predicate is true.
476 /// Action should not be an action that requires mutation.
477 LegalizeRuleSet &actionIf(LegalizeAction Action,
479 add({Predicate, Action});
480 return *this;
481 }
482 /// Use the given action when the predicate is true.
483 /// Action should be an action that requires mutation.
484 LegalizeRuleSet &actionIf(LegalizeAction Action, LegalityPredicate Predicate,
486 add({Predicate, Action, Mutation});
487 return *this;
488 }
489 /// Use the given action when type index 0 is any type in the given list.
490 /// Action should not be an action that requires mutation.
491 LegalizeRuleSet &actionFor(LegalizeAction Action,
492 std::initializer_list<LLT> Types) {
493 using namespace LegalityPredicates;
494 return actionIf(Action, typeInSet(typeIdx(0), Types));
495 }
496 /// Use the given action when type index 0 is any type in the given list.
497 /// Action should be an action that requires mutation.
498 LegalizeRuleSet &actionFor(LegalizeAction Action,
499 std::initializer_list<LLT> Types,
501 using namespace LegalityPredicates;
502 return actionIf(Action, typeInSet(typeIdx(0), Types), Mutation);
503 }
504 /// Use the given action when type indexes 0 and 1 is any type pair in the
505 /// given list.
506 /// Action should not be an action that requires mutation.
507 LegalizeRuleSet &actionFor(LegalizeAction Action,
508 std::initializer_list<std::pair<LLT, LLT>> Types) {
509 using namespace LegalityPredicates;
510 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
511 }
512
514 actionFor(LegalizeAction Action,
515 std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
516 using namespace LegalityPredicates;
517 return actionIf(Action,
518 typeTupleInSet(typeIdx(0), typeIdx(1), typeIdx(2), Types));
519 }
520
521 /// Use the given action when type indexes 0 and 1 is any type pair in the
522 /// given list.
523 /// Action should be an action that requires mutation.
524 LegalizeRuleSet &actionFor(LegalizeAction Action,
525 std::initializer_list<std::pair<LLT, LLT>> Types,
527 using namespace LegalityPredicates;
528 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types),
529 Mutation);
530 }
531 /// Use the given action when type index 0 is any type in the given list and
532 /// imm index 0 is anything. Action should not be an action that requires
533 /// mutation.
534 LegalizeRuleSet &actionForTypeWithAnyImm(LegalizeAction Action,
535 std::initializer_list<LLT> Types) {
536 using namespace LegalityPredicates;
537 immIdx(0); // Inform verifier imm idx 0 is handled.
538 return actionIf(Action, typeInSet(typeIdx(0), Types));
539 }
540
541 LegalizeRuleSet &actionForTypeWithAnyImm(
542 LegalizeAction Action, std::initializer_list<std::pair<LLT, LLT>> Types) {
543 using namespace LegalityPredicates;
544 immIdx(0); // Inform verifier imm idx 0 is handled.
545 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
546 }
547
548 /// Use the given action when type indexes 0 and 1 are both in the given list.
549 /// That is, the type pair is in the cartesian product of the list.
550 /// Action should not be an action that requires mutation.
551 LegalizeRuleSet &actionForCartesianProduct(LegalizeAction Action,
552 std::initializer_list<LLT> Types) {
553 using namespace LegalityPredicates;
554 return actionIf(Action, all(typeInSet(typeIdx(0), Types),
555 typeInSet(typeIdx(1), Types)));
556 }
557 /// Use the given action when type indexes 0 and 1 are both in their
558 /// respective lists.
559 /// That is, the type pair is in the cartesian product of the lists
560 /// Action should not be an action that requires mutation.
562 actionForCartesianProduct(LegalizeAction Action,
563 std::initializer_list<LLT> Types0,
564 std::initializer_list<LLT> Types1) {
565 using namespace LegalityPredicates;
566 return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
567 typeInSet(typeIdx(1), Types1)));
568 }
569 /// Use the given action when type indexes 0, 1, and 2 are all in their
570 /// respective lists.
571 /// That is, the type triple is in the cartesian product of the lists
572 /// Action should not be an action that requires mutation.
573 LegalizeRuleSet &actionForCartesianProduct(
574 LegalizeAction Action, std::initializer_list<LLT> Types0,
575 std::initializer_list<LLT> Types1, std::initializer_list<LLT> Types2) {
576 using namespace LegalityPredicates;
577 return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
578 all(typeInSet(typeIdx(1), Types1),
579 typeInSet(typeIdx(2), Types2))));
580 }
581
582public:
583 LegalizeRuleSet() = default;
584
585 bool isAliasedByAnother() { return IsAliasedByAnother; }
586 void setIsAliasedByAnother() { IsAliasedByAnother = true; }
587 void aliasTo(unsigned Opcode) {
588 assert((AliasOf == 0 || AliasOf == Opcode) &&
589 "Opcode is already aliased to another opcode");
590 assert(Rules.empty() && "Aliasing will discard rules");
591 AliasOf = Opcode;
592 }
593 unsigned getAlias() const { return AliasOf; }
594
595 unsigned immIdx(unsigned ImmIdx) {
598 "Imm Index is out of bounds");
599#ifndef NDEBUG
600 ImmIdxsCovered.set(ImmIdx);
601#endif
602 return ImmIdx;
603 }
604
605 /// The instruction is legal if predicate is true.
607 // We have no choice but conservatively assume that the free-form
608 // user-provided Predicate properly handles all type indices:
609 markAllIdxsAsCovered();
610 return actionIf(LegalizeAction::Legal, Predicate);
611 }
612 /// The instruction is legal when type index 0 is any type in the given list.
613 LegalizeRuleSet &legalFor(std::initializer_list<LLT> Types) {
614 return actionFor(LegalizeAction::Legal, Types);
615 }
616 LegalizeRuleSet &legalFor(bool Pred, std::initializer_list<LLT> Types) {
617 if (!Pred)
618 return *this;
619 return actionFor(LegalizeAction::Legal, Types);
620 }
621 /// The instruction is legal when type indexes 0 and 1 is any type pair in the
622 /// given list.
623 LegalizeRuleSet &legalFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
624 return actionFor(LegalizeAction::Legal, Types);
625 }
627 std::initializer_list<std::pair<LLT, LLT>> Types) {
628 if (!Pred)
629 return *this;
630 return actionFor(LegalizeAction::Legal, Types);
631 }
633 legalFor(bool Pred, std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
634 if (!Pred)
635 return *this;
636 return actionFor(LegalizeAction::Legal, Types);
637 }
638 /// The instruction is legal when type index 0 is any type in the given list
639 /// and imm index 0 is anything.
640 LegalizeRuleSet &legalForTypeWithAnyImm(std::initializer_list<LLT> Types) {
641 markAllIdxsAsCovered();
642 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
643 }
644
646 std::initializer_list<std::pair<LLT, LLT>> Types) {
647 markAllIdxsAsCovered();
648 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
649 }
650
651 /// The instruction is legal when type indexes 0 and 1 along with the memory
652 /// size and minimum alignment is any type and size tuple in the given list.
654 std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
655 TypesAndMemDesc) {
656 return actionIf(LegalizeAction::Legal,
658 typeIdx(0), typeIdx(1), /*MMOIdx*/ 0, TypesAndMemDesc));
659 }
660 /// The instruction is legal when type indexes 0 and 1 are both in the given
661 /// list. That is, the type pair is in the cartesian product of the list.
662 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types) {
663 return actionForCartesianProduct(LegalizeAction::Legal, Types);
664 }
665 /// The instruction is legal when type indexes 0 and 1 are both their
666 /// respective lists.
667 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
668 std::initializer_list<LLT> Types1) {
669 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
670 }
671 /// The instruction is legal when type indexes 0, 1, and 2 are both their
672 /// respective lists.
673 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
674 std::initializer_list<LLT> Types1,
675 std::initializer_list<LLT> Types2) {
676 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1,
677 Types2);
678 }
679
681 using namespace LegalizeMutations;
682 markAllIdxsAsCovered();
683 return actionIf(LegalizeAction::Legal, always);
684 }
685
686 /// The specified type index is coerced if predicate is true.
689 // We have no choice but conservatively assume that lowering with a
690 // free-form user provided Predicate properly handles all type indices:
691 markAllIdxsAsCovered();
692 return actionIf(LegalizeAction::Bitcast, Predicate, Mutation);
693 }
694
695 /// The instruction is lowered.
697 using namespace LegalizeMutations;
698 // We have no choice but conservatively assume that predicate-less lowering
699 // properly handles all type indices by design:
700 markAllIdxsAsCovered();
701 return actionIf(LegalizeAction::Lower, always);
702 }
703 /// The instruction is lowered if predicate is true. Keep type index 0 as the
704 /// same type.
706 using namespace LegalizeMutations;
707 // We have no choice but conservatively assume that lowering with a
708 // free-form user provided Predicate properly handles all type indices:
709 markAllIdxsAsCovered();
710 return actionIf(LegalizeAction::Lower, Predicate);
711 }
712 /// The instruction is lowered if predicate is true.
715 // We have no choice but conservatively assume that lowering with a
716 // free-form user provided Predicate properly handles all type indices:
717 markAllIdxsAsCovered();
718 return actionIf(LegalizeAction::Lower, Predicate, Mutation);
719 }
720 /// The instruction is lowered when type index 0 is any type in the given
721 /// list. Keep type index 0 as the same type.
722 LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types) {
723 return actionFor(LegalizeAction::Lower, Types);
724 }
725 /// The instruction is lowered when type index 0 is any type in the given
726 /// list.
727 LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types,
729 return actionFor(LegalizeAction::Lower, Types, Mutation);
730 }
731 /// The instruction is lowered when type indexes 0 and 1 is any type pair in
732 /// the given list. Keep type index 0 as the same type.
733 LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
734 return actionFor(LegalizeAction::Lower, Types);
735 }
736 /// The instruction is lowered when type indexes 0 and 1 is any type pair in
737 /// the given list.
738 LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types,
740 return actionFor(LegalizeAction::Lower, Types, Mutation);
741 }
742 /// The instruction is lowered when type indexes 0 and 1 are both in their
743 /// respective lists.
744 LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
745 std::initializer_list<LLT> Types1) {
746 using namespace LegalityPredicates;
747 return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1);
748 }
749 /// The instruction is lowered when type indexes 0, 1, and 2 are all in
750 /// their respective lists.
751 LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
752 std::initializer_list<LLT> Types1,
753 std::initializer_list<LLT> Types2) {
754 using namespace LegalityPredicates;
755 return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1,
756 Types2);
757 }
758
759 /// The instruction is emitted as a library call.
761 using namespace LegalizeMutations;
762 // We have no choice but conservatively assume that predicate-less lowering
763 // properly handles all type indices by design:
764 markAllIdxsAsCovered();
765 return actionIf(LegalizeAction::Libcall, always);
766 }
767
768 /// Like legalIf, but for the Libcall action.
770 // We have no choice but conservatively assume that a libcall with a
771 // free-form user provided Predicate properly handles all type indices:
772 markAllIdxsAsCovered();
773 return actionIf(LegalizeAction::Libcall, Predicate);
774 }
775 LegalizeRuleSet &libcallFor(std::initializer_list<LLT> Types) {
776 return actionFor(LegalizeAction::Libcall, Types);
777 }
778 LegalizeRuleSet &libcallFor(bool Pred, std::initializer_list<LLT> Types) {
779 if (!Pred)
780 return *this;
781 return actionFor(LegalizeAction::Libcall, Types);
782 }
784 libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
785 return actionFor(LegalizeAction::Libcall, Types);
786 }
788 libcallFor(bool Pred, std::initializer_list<std::pair<LLT, LLT>> Types) {
789 if (!Pred)
790 return *this;
791 return actionFor(LegalizeAction::Libcall, Types);
792 }
794 libcallForCartesianProduct(std::initializer_list<LLT> Types) {
795 return actionForCartesianProduct(LegalizeAction::Libcall, Types);
796 }
798 libcallForCartesianProduct(std::initializer_list<LLT> Types0,
799 std::initializer_list<LLT> Types1) {
800 return actionForCartesianProduct(LegalizeAction::Libcall, Types0, Types1);
801 }
802
803 /// Widen the scalar to the one selected by the mutation if the predicate is
804 /// true.
807 // We have no choice but conservatively assume that an action with a
808 // free-form user provided Predicate properly handles all type indices:
809 markAllIdxsAsCovered();
810 return actionIf(LegalizeAction::WidenScalar, Predicate, Mutation);
811 }
812 /// Narrow 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::NarrowScalar, Predicate, Mutation);
820 }
821 /// Narrow the scalar, specified in mutation, when type indexes 0 and 1 is any
822 /// type pair in the given list.
824 narrowScalarFor(std::initializer_list<std::pair<LLT, LLT>> Types,
826 return actionFor(LegalizeAction::NarrowScalar, Types, Mutation);
827 }
828
829 /// Add more elements to reach the type selected by the mutation if the
830 /// predicate is true.
833 // We have no choice but conservatively assume that an action with a
834 // free-form user provided Predicate properly handles all type indices:
835 markAllIdxsAsCovered();
836 return actionIf(LegalizeAction::MoreElements, Predicate, Mutation);
837 }
838 /// Remove elements to reach the type selected by the mutation if the
839 /// predicate is true.
842 // We have no choice but conservatively assume that an action with a
843 // free-form user provided Predicate properly handles all type indices:
844 markAllIdxsAsCovered();
845 return actionIf(LegalizeAction::FewerElements, Predicate, Mutation);
846 }
847
848 /// The instruction is unsupported.
850 markAllIdxsAsCovered();
851 return actionIf(LegalizeAction::Unsupported, always);
852 }
854 return actionIf(LegalizeAction::Unsupported, Predicate);
855 }
856
857 LegalizeRuleSet &unsupportedFor(std::initializer_list<LLT> Types) {
858 return actionFor(LegalizeAction::Unsupported, Types);
859 }
860
862 return actionIf(LegalizeAction::Unsupported,
864 }
865
866 /// Lower a memory operation if the memory size, rounded to bytes, is not a
867 /// power of 2. For example, this will not trigger for s1 or s7, but will for
868 /// s24.
870 return actionIf(LegalizeAction::Lower,
872 }
873
874 /// Lower a memory operation if the memory access size is not a round power of
875 /// 2 byte size. This is stricter than lowerIfMemSizeNotPow2, and more likely
876 /// what you want (e.g. this will lower s1, s7 and s24).
878 return actionIf(LegalizeAction::Lower,
880 }
881
883 // We have no choice but conservatively assume that a custom action with a
884 // free-form user provided Predicate properly handles all type indices:
885 markAllIdxsAsCovered();
886 return actionIf(LegalizeAction::Custom, Predicate);
887 }
888 LegalizeRuleSet &customFor(std::initializer_list<LLT> Types) {
889 return actionFor(LegalizeAction::Custom, Types);
890 }
891 LegalizeRuleSet &customFor(bool Pred, std::initializer_list<LLT> Types) {
892 if (!Pred)
893 return *this;
894 return actionFor(LegalizeAction::Custom, Types);
895 }
896
897 /// The instruction is custom when type indexes 0 and 1 is any type pair in
898 /// the given list.
899 LegalizeRuleSet &customFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
900 return actionFor(LegalizeAction::Custom, Types);
901 }
903 std::initializer_list<std::pair<LLT, LLT>> Types) {
904 if (!Pred)
905 return *this;
906 return actionFor(LegalizeAction::Custom, Types);
907 }
908
909 LegalizeRuleSet &customForCartesianProduct(std::initializer_list<LLT> Types) {
910 return actionForCartesianProduct(LegalizeAction::Custom, Types);
911 }
912 /// The instruction is custom when type indexes 0 and 1 are both in their
913 /// respective lists.
915 customForCartesianProduct(std::initializer_list<LLT> Types0,
916 std::initializer_list<LLT> Types1) {
917 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
918 }
919 /// The instruction is custom when type indexes 0, 1, and 2 are all in
920 /// their respective lists.
922 customForCartesianProduct(std::initializer_list<LLT> Types0,
923 std::initializer_list<LLT> Types1,
924 std::initializer_list<LLT> Types2) {
925 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1,
926 Types2);
927 }
928
929 /// Unconditionally custom lower.
931 return customIf(always);
932 }
933
934 /// Widen the scalar to the next power of two that is at least MinSize.
935 /// No effect if the type is a power of two, except if the type is smaller
936 /// than MinSize, or if the type is a vector type.
938 unsigned MinSize = 0) {
939 using namespace LegalityPredicates;
940 return actionIf(
941 LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
943 }
944
945 /// Widen the scalar to the next multiple of Size. No effect if the
946 /// type is not a scalar or is a multiple of Size.
948 unsigned Size) {
949 using namespace LegalityPredicates;
950 return actionIf(
951 LegalizeAction::WidenScalar, sizeNotMultipleOf(typeIdx(TypeIdx), Size),
953 }
954
955 /// Widen the scalar or vector element type to the next power of two that is
956 /// at least MinSize. No effect if the scalar size is a power of two.
958 unsigned MinSize = 0) {
959 using namespace LegalityPredicates;
960 return actionIf(
961 LegalizeAction::WidenScalar, scalarOrEltSizeNotPow2(typeIdx(TypeIdx)),
963 }
964
965 /// Widen the scalar or vector element type to the next power of two that is
966 /// at least MinSize. No effect if the scalar size is a power of two.
968 unsigned MinSize = 0) {
969 using namespace LegalityPredicates;
970 return actionIf(
971 LegalizeAction::WidenScalar,
972 any(scalarOrEltNarrowerThan(TypeIdx, MinSize),
973 scalarOrEltSizeNotPow2(typeIdx(TypeIdx))),
975 }
976
978 using namespace LegalityPredicates;
979 return actionIf(LegalizeAction::NarrowScalar, isScalar(typeIdx(TypeIdx)),
980 Mutation);
981 }
982
983 LegalizeRuleSet &scalarize(unsigned TypeIdx) {
984 using namespace LegalityPredicates;
985 return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)),
987 }
988
990 using namespace LegalityPredicates;
991 return actionIf(LegalizeAction::FewerElements,
992 all(Predicate, isVector(typeIdx(TypeIdx))),
994 }
995
996 /// Ensure the scalar or element is at least as wide as Ty.
997 LegalizeRuleSet &minScalarOrElt(unsigned TypeIdx, const LLT Ty) {
998 using namespace LegalityPredicates;
999 using namespace LegalizeMutations;
1000 return actionIf(LegalizeAction::WidenScalar,
1001 scalarOrEltNarrowerThan(TypeIdx, Ty.getScalarSizeInBits()),
1002 changeElementTo(typeIdx(TypeIdx), Ty));
1003 }
1004
1005 /// Ensure the scalar or element is at least as wide as Ty.
1007 unsigned TypeIdx, const LLT Ty) {
1008 using namespace LegalityPredicates;
1009 using namespace LegalizeMutations;
1010 return actionIf(LegalizeAction::WidenScalar,
1011 all(Predicate, scalarOrEltNarrowerThan(
1012 TypeIdx, Ty.getScalarSizeInBits())),
1013 changeElementTo(typeIdx(TypeIdx), Ty));
1014 }
1015
1016 /// Ensure the vector size is at least as wide as VectorSize by promoting the
1017 /// element.
1019 unsigned VectorSize) {
1020 using namespace LegalityPredicates;
1021 using namespace LegalizeMutations;
1022 return actionIf(
1023 LegalizeAction::WidenScalar,
1024 [=](const LegalityQuery &Query) {
1025 const LLT VecTy = Query.Types[TypeIdx];
1026 return VecTy.isFixedVector() && VecTy.getSizeInBits() < VectorSize;
1027 },
1028 [=](const LegalityQuery &Query) {
1029 const LLT VecTy = Query.Types[TypeIdx];
1030 unsigned NumElts = VecTy.getNumElements();
1031 unsigned MinSize = VectorSize / NumElts;
1032 LLT NewTy = LLT::fixed_vector(NumElts, LLT::scalar(MinSize));
1033 return std::make_pair(TypeIdx, NewTy);
1034 });
1035 }
1036
1037 /// Ensure the scalar is at least as wide as Ty.
1038 LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT Ty) {
1039 using namespace LegalityPredicates;
1040 using namespace LegalizeMutations;
1041 return actionIf(LegalizeAction::WidenScalar,
1042 scalarNarrowerThan(TypeIdx, Ty.getSizeInBits()),
1043 changeTo(typeIdx(TypeIdx), Ty));
1044 }
1045 LegalizeRuleSet &minScalar(bool Pred, unsigned TypeIdx, const LLT Ty) {
1046 if (!Pred)
1047 return *this;
1048 return minScalar(TypeIdx, Ty);
1049 }
1050
1051 /// Ensure the scalar is at least as wide as Ty if condition is met.
1053 const LLT Ty) {
1054 using namespace LegalityPredicates;
1055 using namespace LegalizeMutations;
1056 return actionIf(
1057 LegalizeAction::WidenScalar,
1058 [=](const LegalityQuery &Query) {
1059 const LLT QueryTy = Query.Types[TypeIdx];
1060 return QueryTy.isScalar() &&
1061 QueryTy.getSizeInBits() < Ty.getSizeInBits() &&
1062 Predicate(Query);
1063 },
1064 changeTo(typeIdx(TypeIdx), Ty));
1065 }
1066
1067 /// Ensure the scalar is at most as wide as Ty.
1068 LegalizeRuleSet &maxScalarOrElt(unsigned TypeIdx, const LLT Ty) {
1069 using namespace LegalityPredicates;
1070 using namespace LegalizeMutations;
1071 return actionIf(LegalizeAction::NarrowScalar,
1072 scalarOrEltWiderThan(TypeIdx, Ty.getScalarSizeInBits()),
1073 changeElementTo(typeIdx(TypeIdx), Ty));
1074 }
1075
1076 /// Ensure the scalar is at most as wide as Ty.
1077 LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT Ty) {
1078 using namespace LegalityPredicates;
1079 using namespace LegalizeMutations;
1080 return actionIf(LegalizeAction::NarrowScalar,
1081 scalarWiderThan(TypeIdx, Ty.getSizeInBits()),
1082 changeTo(typeIdx(TypeIdx), Ty));
1083 }
1084
1085 /// Conditionally limit the maximum size of the scalar.
1086 /// For example, when the maximum size of one type depends on the size of
1087 /// another such as extracting N bits from an M bit container.
1089 const LLT Ty) {
1090 using namespace LegalityPredicates;
1091 using namespace LegalizeMutations;
1092 return actionIf(
1093 LegalizeAction::NarrowScalar,
1094 [=](const LegalityQuery &Query) {
1095 const LLT QueryTy = Query.Types[TypeIdx];
1096 return QueryTy.isScalar() &&
1097 QueryTy.getSizeInBits() > Ty.getSizeInBits() &&
1098 Predicate(Query);
1099 },
1100 changeElementTo(typeIdx(TypeIdx), Ty));
1101 }
1102
1103 /// Limit the range of scalar sizes to MinTy and MaxTy.
1104 LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT MinTy,
1105 const LLT MaxTy) {
1106 assert(MinTy.isScalar() && MaxTy.isScalar() && "Expected scalar types");
1107 return minScalar(TypeIdx, MinTy).maxScalar(TypeIdx, MaxTy);
1108 }
1109
1110 LegalizeRuleSet &clampScalar(bool Pred, unsigned TypeIdx, const LLT MinTy,
1111 const LLT MaxTy) {
1112 if (!Pred)
1113 return *this;
1114 return clampScalar(TypeIdx, MinTy, MaxTy);
1115 }
1116
1117 /// Limit the range of scalar sizes to MinTy and MaxTy.
1118 LegalizeRuleSet &clampScalarOrElt(unsigned TypeIdx, const LLT MinTy,
1119 const LLT MaxTy) {
1120 return minScalarOrElt(TypeIdx, MinTy).maxScalarOrElt(TypeIdx, MaxTy);
1121 }
1122
1123 /// Widen the scalar to match the size of another.
1124 LegalizeRuleSet &minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx) {
1125 typeIdx(TypeIdx);
1126 return actionIf(
1127 LegalizeAction::WidenScalar,
1128 [=](const LegalityQuery &Query) {
1129 return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
1130 Query.Types[TypeIdx].getSizeInBits();
1131 },
1132 LegalizeMutations::changeElementSizeTo(TypeIdx, LargeTypeIdx));
1133 }
1134
1135 /// Narrow the scalar to match the size of another.
1136 LegalizeRuleSet &maxScalarSameAs(unsigned TypeIdx, unsigned NarrowTypeIdx) {
1137 typeIdx(TypeIdx);
1138 return actionIf(
1139 LegalizeAction::NarrowScalar,
1140 [=](const LegalityQuery &Query) {
1141 return Query.Types[NarrowTypeIdx].getScalarSizeInBits() <
1142 Query.Types[TypeIdx].getSizeInBits();
1143 },
1144 LegalizeMutations::changeElementSizeTo(TypeIdx, NarrowTypeIdx));
1145 }
1146
1147 /// Change the type \p TypeIdx to have the same scalar size as type \p
1148 /// SameSizeIdx.
1149 LegalizeRuleSet &scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx) {
1150 return minScalarSameAs(TypeIdx, SameSizeIdx)
1151 .maxScalarSameAs(TypeIdx, SameSizeIdx);
1152 }
1153
1154 /// Conditionally widen the scalar or elt to match the size of another.
1156 unsigned TypeIdx, unsigned LargeTypeIdx) {
1157 typeIdx(TypeIdx);
1158 return widenScalarIf(
1159 [=](const LegalityQuery &Query) {
1160 return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
1161 Query.Types[TypeIdx].getScalarSizeInBits() &&
1162 Predicate(Query);
1163 },
1164 [=](const LegalityQuery &Query) {
1165 LLT T = Query.Types[LargeTypeIdx];
1166 if (T.isPointerVector())
1167 T = T.changeElementType(LLT::scalar(T.getScalarSizeInBits()));
1168 return std::make_pair(TypeIdx, T);
1169 });
1170 }
1171
1172 /// Conditionally narrow the scalar or elt to match the size of another.
1174 unsigned TypeIdx,
1175 unsigned SmallTypeIdx) {
1176 typeIdx(TypeIdx);
1177 return narrowScalarIf(
1178 [=](const LegalityQuery &Query) {
1179 return Query.Types[SmallTypeIdx].getScalarSizeInBits() <
1180 Query.Types[TypeIdx].getScalarSizeInBits() &&
1181 Predicate(Query);
1182 },
1183 [=](const LegalityQuery &Query) {
1184 LLT T = Query.Types[SmallTypeIdx];
1185 return std::make_pair(TypeIdx, T);
1186 });
1187 }
1188
1189 /// Add more elements to the vector to reach the next power of two.
1190 /// No effect if the type is not a vector or the element count is a power of
1191 /// two.
1193 using namespace LegalityPredicates;
1194 return actionIf(LegalizeAction::MoreElements,
1195 numElementsNotPow2(typeIdx(TypeIdx)),
1197 }
1198
1199 /// Limit the number of elements in EltTy vectors to at least MinElements.
1200 LegalizeRuleSet &clampMinNumElements(unsigned TypeIdx, const LLT EltTy,
1201 unsigned MinElements) {
1202 // Mark the type index as covered:
1203 typeIdx(TypeIdx);
1204 return actionIf(
1205 LegalizeAction::MoreElements,
1206 [=](const LegalityQuery &Query) {
1207 LLT VecTy = Query.Types[TypeIdx];
1208 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1209 VecTy.getNumElements() < MinElements;
1210 },
1211 [=](const LegalityQuery &Query) {
1212 LLT VecTy = Query.Types[TypeIdx];
1213 return std::make_pair(
1214 TypeIdx, LLT::fixed_vector(MinElements, VecTy.getElementType()));
1215 });
1216 }
1217
1218 /// Set number of elements to nearest larger multiple of NumElts.
1219 LegalizeRuleSet &alignNumElementsTo(unsigned TypeIdx, const LLT EltTy,
1220 unsigned NumElts) {
1221 typeIdx(TypeIdx);
1222 return actionIf(
1223 LegalizeAction::MoreElements,
1224 [=](const LegalityQuery &Query) {
1225 LLT VecTy = Query.Types[TypeIdx];
1226 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1227 (VecTy.getNumElements() % NumElts != 0);
1228 },
1229 [=](const LegalityQuery &Query) {
1230 LLT VecTy = Query.Types[TypeIdx];
1231 unsigned NewSize = alignTo(VecTy.getNumElements(), NumElts);
1232 return std::make_pair(
1233 TypeIdx, LLT::fixed_vector(NewSize, VecTy.getElementType()));
1234 });
1235 }
1236
1237 /// Limit the number of elements in EltTy vectors to at most MaxElements.
1238 LegalizeRuleSet &clampMaxNumElements(unsigned TypeIdx, const LLT EltTy,
1239 unsigned MaxElements) {
1240 // Mark the type index as covered:
1241 typeIdx(TypeIdx);
1242 return actionIf(
1243 LegalizeAction::FewerElements,
1244 [=](const LegalityQuery &Query) {
1245 LLT VecTy = Query.Types[TypeIdx];
1246 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1247 VecTy.getNumElements() > MaxElements;
1248 },
1249 [=](const LegalityQuery &Query) {
1250 LLT VecTy = Query.Types[TypeIdx];
1251 LLT NewTy = LLT::scalarOrVector(ElementCount::getFixed(MaxElements),
1252 VecTy.getElementType());
1253 return std::make_pair(TypeIdx, NewTy);
1254 });
1255 }
1256 /// Limit the number of elements for the given vectors to at least MinTy's
1257 /// number of elements and at most MaxTy's number of elements.
1258 ///
1259 /// No effect if the type is not a vector or does not have the same element
1260 /// type as the constraints.
1261 /// The element type of MinTy and MaxTy must match.
1262 LegalizeRuleSet &clampNumElements(unsigned TypeIdx, const LLT MinTy,
1263 const LLT MaxTy) {
1264 assert(MinTy.getElementType() == MaxTy.getElementType() &&
1265 "Expected element types to agree");
1266
1267 assert((!MinTy.isScalableVector() && !MaxTy.isScalableVector()) &&
1268 "Unexpected scalable vectors");
1269
1270 const LLT EltTy = MinTy.getElementType();
1271 return clampMinNumElements(TypeIdx, EltTy, MinTy.getNumElements())
1272 .clampMaxNumElements(TypeIdx, EltTy, MaxTy.getNumElements());
1273 }
1274
1275 /// Express \p EltTy vectors strictly using vectors with \p NumElts elements
1276 /// (or scalars when \p NumElts equals 1).
1277 /// First pad with undef elements to nearest larger multiple of \p NumElts.
1278 /// Then perform split with all sub-instructions having the same type.
1279 /// Using clampMaxNumElements (non-strict) can result in leftover instruction
1280 /// with different type (fewer elements then \p NumElts or scalar).
1281 /// No effect if the type is not a vector.
1282 LegalizeRuleSet &clampMaxNumElementsStrict(unsigned TypeIdx, const LLT EltTy,
1283 unsigned NumElts) {
1284 return alignNumElementsTo(TypeIdx, EltTy, NumElts)
1285 .clampMaxNumElements(TypeIdx, EltTy, NumElts);
1286 }
1287
1288 /// Fallback on the previous implementation. This should only be used while
1289 /// porting a rule.
1291 add({always, LegalizeAction::UseLegacyRules});
1292 return *this;
1293 }
1294
1295 /// Check if there is no type index which is obviously not handled by the
1296 /// LegalizeRuleSet in any way at all.
1297 /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
1298 bool verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const;
1299 /// Check if there is no imm index which is obviously not handled by the
1300 /// LegalizeRuleSet in any way at all.
1301 /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
1302 bool verifyImmIdxsCoverage(unsigned NumImmIdxs) const;
1303
1304 /// Apply the ruleset to the given LegalityQuery.
1305 LegalizeActionStep apply(const LegalityQuery &Query) const;
1306};
1307
1309public:
1310 virtual ~LegalizerInfo() = default;
1311
1313 return LegacyInfo;
1314 }
1316
1317 unsigned getOpcodeIdxForOpcode(unsigned Opcode) const;
1318 unsigned getActionDefinitionsIdx(unsigned Opcode) const;
1319
1320 /// Perform simple self-diagnostic and assert if there is anything obviously
1321 /// wrong with the actions set up.
1322 void verify(const MCInstrInfo &MII) const;
1323
1324 /// Get the action definitions for the given opcode. Use this to run a
1325 /// LegalityQuery through the definitions.
1326 const LegalizeRuleSet &getActionDefinitions(unsigned Opcode) const;
1327
1328 /// Get the action definition builder for the given opcode. Use this to define
1329 /// the action definitions.
1330 ///
1331 /// It is an error to request an opcode that has already been requested by the
1332 /// multiple-opcode variant.
1334
1335 /// Get the action definition builder for the given set of opcodes. Use this
1336 /// to define the action definitions for multiple opcodes at once. The first
1337 /// opcode given will be considered the representative opcode and will hold
1338 /// the definitions whereas the other opcodes will be configured to refer to
1339 /// the representative opcode. This lowers memory requirements and very
1340 /// slightly improves performance.
1341 ///
1342 /// It would be very easy to introduce unexpected side-effects as a result of
1343 /// this aliasing if it were permitted to request different but intersecting
1344 /// sets of opcodes but that is difficult to keep track of. It is therefore an
1345 /// error to request the same opcode twice using this API, to request an
1346 /// opcode that already has definitions, or to use the single-opcode API on an
1347 /// opcode that has already been requested by this API.
1349 getActionDefinitionsBuilder(std::initializer_list<unsigned> Opcodes);
1350 void aliasActionDefinitions(unsigned OpcodeTo, unsigned OpcodeFrom);
1351
1352 /// Determine what action should be taken to legalize the described
1353 /// instruction. Requires computeTables to have been called.
1354 ///
1355 /// \returns a description of the next legalization step to perform.
1356 LegalizeActionStep getAction(const LegalityQuery &Query) const;
1357
1358 /// Determine what action should be taken to legalize the given generic
1359 /// instruction.
1360 ///
1361 /// \returns a description of the next legalization step to perform.
1363 const MachineRegisterInfo &MRI) const;
1364
1365 bool isLegal(const LegalityQuery &Query) const {
1366 return getAction(Query).Action == LegalizeAction::Legal;
1367 }
1368
1369 bool isLegalOrCustom(const LegalityQuery &Query) const {
1370 auto Action = getAction(Query).Action;
1371 return Action == LegalizeAction::Legal || Action == LegalizeAction::Custom;
1372 }
1373
1374 bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
1375 bool isLegalOrCustom(const MachineInstr &MI,
1376 const MachineRegisterInfo &MRI) const;
1377
1378 /// Called for instructions with the Custom LegalizationAction.
1380 LostDebugLocObserver &LocObserver) const {
1381 llvm_unreachable("must implement this if custom action is used");
1382 }
1383
1384 /// \returns true if MI is either legal or has been legalized and false if not
1385 /// legal.
1386 /// Return true if MI is either legal or has been legalized and false
1387 /// if not legal.
1389 MachineInstr &MI) const {
1390 return true;
1391 }
1392
1393 /// Return the opcode (SEXT/ZEXT/ANYEXT) that should be performed while
1394 /// widening a constant of type SmallTy which targets can override.
1395 /// For eg, the DAG does (SmallTy.isByteSized() ? G_SEXT : G_ZEXT) which
1396 /// will be the default.
1397 virtual unsigned getExtOpcodeForWideningConstant(LLT SmallTy) const;
1398
1399private:
1400 static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
1401 static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
1402
1403 LegalizeRuleSet RulesForOpcode[LastOp - FirstOp + 1];
1404 LegacyLegalizerInfo LegacyInfo;
1405};
1406
1407#ifndef NDEBUG
1408/// Checks that MIR is fully legal, returns an illegal instruction if it's not,
1409/// nullptr otherwise
1410const MachineInstr *machineFunctionIsIllegal(const MachineFunction &MF);
1411#endif
1412
1413} // end namespace llvm.
1414
1415#endif // LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
unsigned const MachineRegisterInfo * MRI
Atomic ordering constants.
Given that RA is a live value
uint64_t Size
ELFYAML::ELF_REL Type2
Definition: ELFYAML.cpp:1837
IRTranslator LLVM IR MI
Interface for Targets to specify which operations they can successfully select and how the others sho...
Implement a low-level type suitable for MachineInstr level instruction selection.
nvptx lower args
#define P(N)
ppc ctr loops verify
PowerPC VSX FMA Mutation
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file implements the SmallBitVector class.
This file defines the SmallVector class.
Value * RHS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition: TypeSize.h:311
constexpr bool isScalableVector() const
Returns true if the LLT is a scalable vector.
Definition: LowLevelType.h:181
constexpr unsigned getScalarSizeInBits() const
Definition: LowLevelType.h:264
constexpr bool isScalar() const
Definition: LowLevelType.h:146
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:42
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
Definition: LowLevelType.h:159
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelType.h:190
constexpr LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
Definition: LowLevelType.h:277
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
Definition: LowLevelType.h:100
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
Definition: LowLevelType.h:177
static constexpr LLT scalarOrVector(ElementCount EC, LLT ScalarTy)
Definition: LowLevelType.h:124
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 & legalFor(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list.
LegalizeRuleSet & maxScalarEltSameAsIf(LegalityPredicate Predicate, unsigned TypeIdx, unsigned SmallTypeIdx)
Conditionally narrow the scalar or elt to match the size of another.
LegalizeRuleSet & unsupported()
The instruction is unsupported.
LegalizeRuleSet & legalFor(bool Pred, std::initializer_list< std::tuple< LLT, LLT, LLT > > Types)
LegalizeRuleSet & scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx)
Change the type TypeIdx to have the same scalar size as type SameSizeIdx.
LegalizeRuleSet & fewerElementsIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Remove elements to reach the type selected by the mutation if the predicate is true.
LegalizeRuleSet & clampScalarOrElt(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
void aliasTo(unsigned Opcode)
LegalizeRuleSet & bitcastIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
The specified type index is coerced if predicate is true.
LegalizeRuleSet & libcall()
The instruction is emitted as a library call.
LegalizeRuleSet & libcallFor(std::initializer_list< LLT > Types)
bool verifyImmIdxsCoverage(unsigned NumImmIdxs) const
Check if there is no imm index which is obviously not handled by the LegalizeRuleSet in any way at al...
LegalizeRuleSet & maxScalar(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at most as wide as Ty.
LegalizeRuleSet & minScalarOrElt(unsigned TypeIdx, const LLT Ty)
Ensure the scalar or element is at least as wide as Ty.
LegalizeRuleSet & clampMaxNumElements(unsigned TypeIdx, const LLT EltTy, unsigned MaxElements)
Limit the number of elements in EltTy vectors to at most MaxElements.
LegalizeRuleSet & clampMinNumElements(unsigned TypeIdx, const LLT EltTy, unsigned MinElements)
Limit the number of elements in EltTy vectors to at least MinElements.
LegalizeRuleSet & libcallForCartesianProduct(std::initializer_list< LLT > Types)
LegalizeRuleSet & unsupportedFor(std::initializer_list< LLT > Types)
LegalizeRuleSet & legalFor(bool Pred, std::initializer_list< LLT > Types)
LegalizeRuleSet & widenVectorEltsToVectorMinSize(unsigned TypeIdx, unsigned VectorSize)
Ensure the vector size is at least as wide as VectorSize by promoting the element.
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is legal when type indexes 0 and 1 are both their respective lists.
LegalizeRuleSet & lowerIfMemSizeNotPow2()
Lower a memory operation if the memory size, rounded to bytes, is not a power of 2.
LegalizeRuleSet & lowerFor(std::initializer_list< LLT > Types, LegalizeMutation Mutation)
The instruction is lowered when type index 0 is any type in the given list.
LegalizeRuleSet & minScalarEltSameAsIf(LegalityPredicate Predicate, unsigned TypeIdx, unsigned LargeTypeIdx)
Conditionally widen the scalar or elt to match the size of another.
LegalizeRuleSet & customForCartesianProduct(std::initializer_list< LLT > Types)
LegalizeRuleSet & lowerIfMemSizeNotByteSizePow2()
Lower a memory operation if the memory access size is not a round power of 2 byte size.
LegalizeRuleSet & minScalar(bool Pred, unsigned TypeIdx, const LLT Ty)
LegalizeRuleSet & moreElementsToNextPow2(unsigned TypeIdx)
Add more elements to the vector to reach the next power of two.
LegalizeRuleSet & customForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is custom when type indexes 0 and 1 are both in their respective lists.
LegalizeRuleSet & legalForTypeWithAnyImm(std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & lowerFor(std::initializer_list< std::pair< LLT, LLT > > Types)
The instruction is lowered when type indexes 0 and 1 is any type pair in the given list.
LegalizeRuleSet & narrowScalarIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Narrow the scalar to the one selected by the mutation if the predicate is true.
LegalizeRuleSet & lower()
The instruction is lowered.
LegalizeRuleSet & moreElementsIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Add more elements to reach the type selected by the mutation if the predicate is true.
LegalizeRuleSet & narrowScalarFor(std::initializer_list< std::pair< LLT, LLT > > Types, LegalizeMutation Mutation)
Narrow the scalar, specified in mutation, when type indexes 0 and 1 is any type pair in the given lis...
LegalizeRuleSet & narrowScalar(unsigned TypeIdx, LegalizeMutation Mutation)
LegalizeRuleSet & customFor(bool Pred, std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & lowerFor(std::initializer_list< LLT > Types)
The instruction is lowered when type index 0 is any type in the given list.
LegalizeRuleSet & scalarizeIf(LegalityPredicate Predicate, unsigned TypeIdx)
LegalizeRuleSet & lowerIf(LegalityPredicate Predicate)
The instruction is lowered if predicate is true.
LegalizeRuleSet & clampScalar(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1, std::initializer_list< LLT > Types2)
The instruction is legal when type indexes 0, 1, and 2 are both their respective lists.
LegalizeRuleSet & alignNumElementsTo(unsigned TypeIdx, const LLT EltTy, unsigned NumElts)
Set number of elements to nearest larger multiple of NumElts.
LegalizeRuleSet & custom()
Unconditionally custom lower.
LegalizeRuleSet & libcallForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
LegalizeRuleSet & clampMaxNumElementsStrict(unsigned TypeIdx, const LLT EltTy, unsigned NumElts)
Express EltTy vectors strictly using vectors with NumElts elements (or scalars when NumElts equals 1)...
LegalizeRuleSet & minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx)
Widen the scalar to match the size of another.
LegalizeRuleSet & unsupportedIf(LegalityPredicate Predicate)
LegalizeRuleSet & minScalarOrEltIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT Ty)
Ensure the scalar or element is at least as wide as Ty.
LegalizeRuleSet & widenScalarIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Widen the scalar to the one selected by the mutation if the predicate is true.
LegalizeRuleSet & libcallFor(std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & customFor(bool Pred, std::initializer_list< LLT > Types)
LegalizeRuleSet & fallback()
Fallback on the previous implementation.
LegalizeRuleSet & legalForTypeWithAnyImm(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list and imm index 0 is anything.
LegalizeRuleSet & lowerForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1, std::initializer_list< LLT > Types2)
The instruction is lowered when type indexes 0, 1, and 2 are all in their respective lists.
LegalizeRuleSet & legalFor(std::initializer_list< std::pair< LLT, LLT > > Types)
The instruction is legal when type indexes 0 and 1 is any type pair in the given list.
LegalizeRuleSet & libcallFor(bool Pred, std::initializer_list< LLT > Types)
LegalizeRuleSet & libcallFor(bool Pred, std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & alwaysLegal()
LegalizeRuleSet & legalFor(bool Pred, std::initializer_list< std::pair< LLT, LLT > > Types)
unsigned getAlias() const
LegalizeRuleSet & clampNumElements(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the number of elements for the given vectors to at least MinTy's number of elements and at most...
LegalizeRuleSet & unsupportedIfMemSizeNotPow2()
LegalizeRuleSet & maxScalarIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT Ty)
Conditionally limit the maximum size of the scalar.
LegalizeRuleSet & customIf(LegalityPredicate Predicate)
LegalizeRuleSet & customForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1, std::initializer_list< LLT > Types2)
The instruction is custom when type indexes 0, 1, and 2 are all in their respective lists.
LegalizeRuleSet & widenScalarToNextPow2(unsigned TypeIdx, unsigned MinSize=0)
Widen the scalar to the next power of two that is at least MinSize.
LegalizeRuleSet & scalarize(unsigned TypeIdx)
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types)
The instruction is legal when type indexes 0 and 1 are both in the given list.
LegalizeRuleSet & lowerForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is lowered when type indexes 0 and 1 are both in their respective lists.
LegalizeRuleSet & lowerIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
The instruction is lowered if predicate is true.
LegalizeRuleSet & legalForTypesWithMemDesc(std::initializer_list< LegalityPredicates::TypePairAndMemDesc > TypesAndMemDesc)
The instruction is legal when type indexes 0 and 1 along with the memory size and minimum alignment i...
LegalizeRuleSet & libcallIf(LegalityPredicate Predicate)
Like legalIf, but for the Libcall action.
LegalizeRuleSet & maxScalarOrElt(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at most as wide as Ty.
LegalizeRuleSet & customFor(std::initializer_list< std::pair< LLT, LLT > > Types)
The instruction is custom when type indexes 0 and 1 is any type pair in the given list.
LegalizeRuleSet & minScalarIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at least as wide as Ty if condition is met.
unsigned immIdx(unsigned ImmIdx)
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.
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.
const LegacyLegalizerInfo & getLegacyLegalizerInfo() const
virtual unsigned getExtOpcodeForWideningConstant(LLT SmallTy) const
Return the opcode (SEXT/ZEXT/ANYEXT) that should be performed while widening a constant of type Small...
LegacyLegalizerInfo & getLegacyLegalizerInfo()
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:26
Representation of each machine instruction.
Definition: MachineInstr.h:71
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 ...
SmallBitVector & set()
bool empty() const
Definition: SmallVector.h:81
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MoreElements
The (vector) operation should be implemented by widening the input vector and ignoring the lanes adde...
@ Legal
The operation is expected to be selectable directly by the target, and no transformation is necessary...
@ FewerElements
The (vector) operation should be implemented by splitting it into sub-vectors where the operation is ...
@ Unsupported
This operation is completely unsupported on the target.
@ NarrowScalar
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type.
@ Lower
The operation itself must be expressed in terms of simpler actions on this target.
@ 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.
@ WidenScalar
The operation should be implemented in terms of a wider scalar base-type.
@ Libcall
The operation should be implemented as a call to some kind of runtime support library.
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 ...
LegalityPredicate isScalar(unsigned TypeIdx)
True iff the specified type index is a scalar.
LegalityPredicate memSizeInBytesNotPow2(unsigned MMOIdx)
True iff the specified MMO index has a size (rounded to bytes) that is not a power of 2.
LegalityPredicate numElementsNotPow2(unsigned TypeIdx)
True iff the specified type index is a vector whose element count is not a power of 2.
LegalityPredicate isPointerVector(unsigned TypeIdx)
True iff the specified type index is a vector of pointers (with any address space).
LegalityPredicate isPointer(unsigned TypeIdx)
True iff the specified type index is a pointer (with any address space).
LegalityPredicate typeInSet(unsigned TypeIdx, std::initializer_list< LLT > TypesInit)
True iff the given type index is one of the specified types.
LegalityPredicate smallerThan(unsigned TypeIdx0, unsigned TypeIdx1)
True iff the first type index has a smaller total bit size than second type index.
LegalityPredicate atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx, AtomicOrdering Ordering)
True iff the specified MMO index has at an atomic ordering of at Ordering or stronger.
LegalityPredicate scalarOrEltSizeNotPow2(unsigned TypeIdx)
True iff the specified type index is a scalar or vector whose element size is not a power of 2.
LegalityPredicate largerThan(unsigned TypeIdx0, unsigned TypeIdx1)
True iff the first type index has a larger total bit size than second type index.
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.
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.
LegalityPredicate elementTypeIs(unsigned TypeIdx, LLT EltTy)
True if the type index is a vector with element type EltTy.
LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1)
True iff the specified type indices are both the same bit size.
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...
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.
LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
LegalityPredicate sizeNotPow2(unsigned TypeIdx)
True iff the specified type index is a scalar whose size is not a power of.
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.
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.
LegalityPredicate sizeNotMultipleOf(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar whose size is not a multiple of Size.
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.
LegalityPredicate scalarWiderThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar that's wider than the given size.
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 ...
Definition: LegalizerInfo.h:65
@ Legal
The operation is expected to be selectable directly by the target, and no transformation is necessary...
Definition: LegalizerInfo.h:47
@ Libcall
The operation should be implemented as a call to some kind of runtime support library.
Definition: LegalizerInfo.h:83
@ Unsupported
This operation is completely unsupported on the target.
Definition: LegalizerInfo.h:91
@ Lower
The operation itself must be expressed in terms of simpler actions on this target.
Definition: LegalizerInfo.h:78
@ UseLegacyRules
Fall back onto the old rules.
Definition: LegalizerInfo.h:98
@ WidenScalar
The operation should be implemented in terms of a wider scalar base-type.
Definition: LegalizerInfo.h:57
@ Bitcast
Perform the operation on a different, but equivalently sized type.
Definition: LegalizerInfo.h:74
@ NarrowScalar
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type.
Definition: LegalizerInfo.h:52
@ Custom
The target wants to do something special with this combination of operand and type.
Definition: LegalizerInfo.h:87
@ NotFound
Sentinel value for when no action was found in the specified table.
Definition: LegalizerInfo.h:94
@ MoreElements
The (vector) operation should be implemented by widening the input vector and ignoring the lanes adde...
Definition: LegalizerInfo.h:71
LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min=0)
Add more elements to the type for the given type index to the next power of.
LegalizeMutation changeElementCountTo(unsigned TypeIdx, unsigned FromTypeIdx)
Keep the same scalar or element type as TypeIdx, but take the number of elements from FromTypeIdx.
LegalizeMutation scalarize(unsigned TypeIdx)
Break up the vector type for the given type index into the element type.
LegalizeMutation changeElementTo(unsigned TypeIdx, unsigned FromTypeIdx)
Keep the same scalar or element type as the given type index.
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.
LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty)
Select this specific type for the given type index.
LegalizeMutation widenScalarOrEltToNextMultipleOf(unsigned TypeIdx, unsigned Size)
Widen the scalar type or vector element type for the given type index to next multiple of Size.
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:72
@ OPERAND_FIRST_GENERIC
Definition: MCInstrDesc.h:65
@ OPERAND_FIRST_GENERIC_IMM
Definition: MCInstrDesc.h:74
@ OPERAND_LAST_GENERIC_IMM
Definition: MCInstrDesc.h:76
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MaybeAlign getAlign(const Function &F, unsigned Index)
cl::opt< bool > DisableGISelLegalityCheck
std::function< std::pair< unsigned, LLT >(const LegalityQuery &)> LegalizeMutation
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.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:303
std::function< bool(const LegalityQuery &)> LegalityPredicate
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
LegacyLegalizeActions::LegacyLegalizeAction Action
The action to take or the final answer.
bool operator==(const TypePairAndMemDesc &Other) const
bool isCompatible(const TypePairAndMemDesc &Other) const
MemDesc(const MachineMemOperand &MMO)
MemDesc(LLT MemoryTy, uint64_t AlignInBits, AtomicOrdering Ordering)
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
raw_ostream & print(raw_ostream &OS) const
constexpr LegalityQuery(unsigned Opcode, ArrayRef< LLT > Types, ArrayRef< MemDesc > MMODescrs={})
The result of a query.
LegalizeAction Action
The action to take or the final answer.
LegalizeActionStep(LegacyLegalizeActionStep Step)
LLT NewType
If describing an action, the new type for TypeIdx. Otherwise LLT{}.
unsigned TypeIdx
If describing an action, the type index to change. Otherwise zero.
LegalizeActionStep(LegalizeAction Action, unsigned TypeIdx, const LLT NewType)
bool operator==(const LegalizeActionStep &RHS) const