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