Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:25

0001 //===- llvm/CodeGen/GlobalISel/LegalizerInfo.h ------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 /// \file
0009 /// Interface for Targets to specify which operations they can successfully
0010 /// select and how the others should be expanded most efficiently.
0011 ///
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
0015 #define LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
0016 
0017 #include "llvm/ADT/SmallBitVector.h"
0018 #include "llvm/ADT/SmallVector.h"
0019 #include "llvm/CodeGen/GlobalISel/LegacyLegalizerInfo.h"
0020 #include "llvm/CodeGen/MachineMemOperand.h"
0021 #include "llvm/CodeGen/TargetOpcodes.h"
0022 #include "llvm/CodeGenTypes/LowLevelType.h"
0023 #include "llvm/MC/MCInstrDesc.h"
0024 #include "llvm/Support/AtomicOrdering.h"
0025 #include "llvm/Support/CommandLine.h"
0026 #include <cassert>
0027 #include <cstdint>
0028 #include <tuple>
0029 #include <utility>
0030 
0031 namespace llvm {
0032 
0033 extern cl::opt<bool> DisableGISelLegalityCheck;
0034 
0035 class MachineFunction;
0036 class raw_ostream;
0037 class LegalizerHelper;
0038 class LostDebugLocObserver;
0039 class MachineInstr;
0040 class MachineRegisterInfo;
0041 class MCInstrInfo;
0042 
0043 namespace LegalizeActions {
0044 enum LegalizeAction : std::uint8_t {
0045   /// The operation is expected to be selectable directly by the target, and
0046   /// no transformation is necessary.
0047   Legal,
0048 
0049   /// The operation should be synthesized from multiple instructions acting on
0050   /// a narrower scalar base-type. For example a 64-bit add might be
0051   /// implemented in terms of 32-bit add-with-carry.
0052   NarrowScalar,
0053 
0054   /// The operation should be implemented in terms of a wider scalar
0055   /// base-type. For example a <2 x s8> add could be implemented as a <2
0056   /// x s32> add (ignoring the high bits).
0057   WidenScalar,
0058 
0059   /// The (vector) operation should be implemented by splitting it into
0060   /// sub-vectors where the operation is legal. For example a <8 x s64> add
0061   /// might be implemented as 4 separate <2 x s64> adds. There can be a leftover
0062   /// if there are not enough elements for last sub-vector e.g. <7 x s64> add
0063   /// will be implemented as 3 separate <2 x s64> adds and one s64 add. Leftover
0064   /// types can be avoided by doing MoreElements first.
0065   FewerElements,
0066 
0067   /// The (vector) operation should be implemented by widening the input
0068   /// vector and ignoring the lanes added by doing so. For example <2 x i8> is
0069   /// rarely legal, but you might perform an <8 x i8> and then only look at
0070   /// the first two results.
0071   MoreElements,
0072 
0073   /// Perform the operation on a different, but equivalently sized type.
0074   Bitcast,
0075 
0076   /// The operation itself must be expressed in terms of simpler actions on
0077   /// this target. E.g. a SREM replaced by an SDIV and subtraction.
0078   Lower,
0079 
0080   /// The operation should be implemented as a call to some kind of runtime
0081   /// support library. For example this usually happens on machines that don't
0082   /// support floating-point operations natively.
0083   Libcall,
0084 
0085   /// The target wants to do something special with this combination of
0086   /// operand and type. A callback will be issued when it is needed.
0087   Custom,
0088 
0089   /// This operation is completely unsupported on the target. A programming
0090   /// error has occurred.
0091   Unsupported,
0092 
0093   /// Sentinel value for when no action was found in the specified table.
0094   NotFound,
0095 
0096   /// Fall back onto the old rules.
0097   /// TODO: Remove this once we've migrated
0098   UseLegacyRules,
0099 };
0100 } // end namespace LegalizeActions
0101 raw_ostream &operator<<(raw_ostream &OS, LegalizeActions::LegalizeAction Action);
0102 
0103 using LegalizeActions::LegalizeAction;
0104 
0105 /// The LegalityQuery object bundles together all the information that's needed
0106 /// to decide whether a given operation is legal or not.
0107 /// For efficiency, it doesn't make a copy of Types so care must be taken not
0108 /// to free it before using the query.
0109 struct LegalityQuery {
0110   unsigned Opcode;
0111   ArrayRef<LLT> Types;
0112 
0113   struct MemDesc {
0114     LLT MemoryTy;
0115     uint64_t AlignInBits;
0116     AtomicOrdering Ordering;
0117 
0118     MemDesc() = default;
0119     MemDesc(LLT MemoryTy, uint64_t AlignInBits, AtomicOrdering Ordering)
0120         : MemoryTy(MemoryTy), AlignInBits(AlignInBits), Ordering(Ordering) {}
0121     MemDesc(const MachineMemOperand &MMO)
0122         : MemoryTy(MMO.getMemoryType()),
0123           AlignInBits(MMO.getAlign().value() * 8),
0124           Ordering(MMO.getSuccessOrdering()) {}
0125   };
0126 
0127   /// Operations which require memory can use this to place requirements on the
0128   /// memory type for each MMO.
0129   ArrayRef<MemDesc> MMODescrs;
0130 
0131   constexpr LegalityQuery(unsigned Opcode, const ArrayRef<LLT> Types,
0132                           const ArrayRef<MemDesc> MMODescrs)
0133       : Opcode(Opcode), Types(Types), MMODescrs(MMODescrs) {}
0134   constexpr LegalityQuery(unsigned Opcode, const ArrayRef<LLT> Types)
0135       : LegalityQuery(Opcode, Types, {}) {}
0136 
0137   raw_ostream &print(raw_ostream &OS) const;
0138 };
0139 
0140 /// The result of a query. It either indicates a final answer of Legal or
0141 /// Unsupported or describes an action that must be taken to make an operation
0142 /// more legal.
0143 struct LegalizeActionStep {
0144   /// The action to take or the final answer.
0145   LegalizeAction Action;
0146   /// If describing an action, the type index to change. Otherwise zero.
0147   unsigned TypeIdx;
0148   /// If describing an action, the new type for TypeIdx. Otherwise LLT{}.
0149   LLT NewType;
0150 
0151   LegalizeActionStep(LegalizeAction Action, unsigned TypeIdx,
0152                      const LLT NewType)
0153       : Action(Action), TypeIdx(TypeIdx), NewType(NewType) {}
0154 
0155   LegalizeActionStep(LegacyLegalizeActionStep Step)
0156       : TypeIdx(Step.TypeIdx), NewType(Step.NewType) {
0157     switch (Step.Action) {
0158     case LegacyLegalizeActions::Legal:
0159       Action = LegalizeActions::Legal;
0160       break;
0161     case LegacyLegalizeActions::NarrowScalar:
0162       Action = LegalizeActions::NarrowScalar;
0163       break;
0164     case LegacyLegalizeActions::WidenScalar:
0165       Action = LegalizeActions::WidenScalar;
0166       break;
0167     case LegacyLegalizeActions::FewerElements:
0168       Action = LegalizeActions::FewerElements;
0169       break;
0170     case LegacyLegalizeActions::MoreElements:
0171       Action = LegalizeActions::MoreElements;
0172       break;
0173     case LegacyLegalizeActions::Bitcast:
0174       Action = LegalizeActions::Bitcast;
0175       break;
0176     case LegacyLegalizeActions::Lower:
0177       Action = LegalizeActions::Lower;
0178       break;
0179     case LegacyLegalizeActions::Libcall:
0180       Action = LegalizeActions::Libcall;
0181       break;
0182     case LegacyLegalizeActions::Custom:
0183       Action = LegalizeActions::Custom;
0184       break;
0185     case LegacyLegalizeActions::Unsupported:
0186       Action = LegalizeActions::Unsupported;
0187       break;
0188     case LegacyLegalizeActions::NotFound:
0189       Action = LegalizeActions::NotFound;
0190       break;
0191     }
0192   }
0193 
0194   bool operator==(const LegalizeActionStep &RHS) const {
0195     return std::tie(Action, TypeIdx, NewType) ==
0196         std::tie(RHS.Action, RHS.TypeIdx, RHS.NewType);
0197   }
0198 };
0199 
0200 using LegalityPredicate = std::function<bool (const LegalityQuery &)>;
0201 using LegalizeMutation =
0202     std::function<std::pair<unsigned, LLT>(const LegalityQuery &)>;
0203 
0204 namespace LegalityPredicates {
0205 struct TypePairAndMemDesc {
0206   LLT Type0;
0207   LLT Type1;
0208   LLT MemTy;
0209   uint64_t Align;
0210 
0211   bool operator==(const TypePairAndMemDesc &Other) const {
0212     return Type0 == Other.Type0 && Type1 == Other.Type1 &&
0213            Align == Other.Align && MemTy == Other.MemTy;
0214   }
0215 
0216   /// \returns true if this memory access is legal with for the access described
0217   /// by \p Other (The alignment is sufficient for the size and result type).
0218   bool isCompatible(const TypePairAndMemDesc &Other) const {
0219     return Type0 == Other.Type0 && Type1 == Other.Type1 &&
0220            Align >= Other.Align &&
0221            // FIXME: This perhaps should be stricter, but the current legality
0222            // rules are written only considering the size.
0223            MemTy.getSizeInBits() == Other.MemTy.getSizeInBits();
0224   }
0225 };
0226 
0227 /// True iff P is false.
0228 template <typename Predicate> Predicate predNot(Predicate P) {
0229   return [=](const LegalityQuery &Query) { return !P(Query); };
0230 }
0231 
0232 /// True iff P0 and P1 are true.
0233 template<typename Predicate>
0234 Predicate all(Predicate P0, Predicate P1) {
0235   return [=](const LegalityQuery &Query) {
0236     return P0(Query) && P1(Query);
0237   };
0238 }
0239 /// True iff all given predicates are true.
0240 template<typename Predicate, typename... Args>
0241 Predicate all(Predicate P0, Predicate P1, Args... args) {
0242   return all(all(P0, P1), args...);
0243 }
0244 
0245 /// True iff P0 or P1 are true.
0246 template<typename Predicate>
0247 Predicate any(Predicate P0, Predicate P1) {
0248   return [=](const LegalityQuery &Query) {
0249     return P0(Query) || P1(Query);
0250   };
0251 }
0252 /// True iff any given predicates are true.
0253 template<typename Predicate, typename... Args>
0254 Predicate any(Predicate P0, Predicate P1, Args... args) {
0255   return any(any(P0, P1), args...);
0256 }
0257 
0258 /// True iff the given type index is the specified type.
0259 LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit);
0260 /// True iff the given type index is one of the specified types.
0261 LegalityPredicate typeInSet(unsigned TypeIdx,
0262                             std::initializer_list<LLT> TypesInit);
0263 
0264 /// True iff the given type index is not the specified type.
0265 inline LegalityPredicate typeIsNot(unsigned TypeIdx, LLT Type) {
0266   return [=](const LegalityQuery &Query) {
0267            return Query.Types[TypeIdx] != Type;
0268          };
0269 }
0270 
0271 /// True iff the given types for the given pair of type indexes is one of the
0272 /// specified type pairs.
0273 LegalityPredicate
0274 typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1,
0275               std::initializer_list<std::pair<LLT, LLT>> TypesInit);
0276 /// True iff the given types for the given tuple of type indexes is one of the
0277 /// specified type tuple.
0278 LegalityPredicate
0279 typeTupleInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned Type2,
0280                std::initializer_list<std::tuple<LLT, LLT, LLT>> TypesInit);
0281 /// True iff the given types for the given pair of type indexes is one of the
0282 /// specified type pairs.
0283 LegalityPredicate typePairAndMemDescInSet(
0284     unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx,
0285     std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit);
0286 /// True iff the specified type index is a scalar.
0287 LegalityPredicate isScalar(unsigned TypeIdx);
0288 /// True iff the specified type index is a vector.
0289 LegalityPredicate isVector(unsigned TypeIdx);
0290 /// True iff the specified type index is a pointer (with any address space).
0291 LegalityPredicate isPointer(unsigned TypeIdx);
0292 /// True iff the specified type index is a pointer with the specified address
0293 /// space.
0294 LegalityPredicate isPointer(unsigned TypeIdx, unsigned AddrSpace);
0295 /// True iff the specified type index is a vector of pointers (with any address
0296 /// space).
0297 LegalityPredicate isPointerVector(unsigned TypeIdx);
0298 
0299 /// True if the type index is a vector with element type \p EltTy
0300 LegalityPredicate elementTypeIs(unsigned TypeIdx, LLT EltTy);
0301 
0302 /// True iff the specified type index is a scalar that's narrower than the given
0303 /// size.
0304 LegalityPredicate scalarNarrowerThan(unsigned TypeIdx, unsigned Size);
0305 
0306 /// True iff the specified type index is a scalar that's wider than the given
0307 /// size.
0308 LegalityPredicate scalarWiderThan(unsigned TypeIdx, unsigned Size);
0309 
0310 /// True iff the specified type index is a scalar or vector with an element type
0311 /// that's narrower than the given size.
0312 LegalityPredicate scalarOrEltNarrowerThan(unsigned TypeIdx, unsigned Size);
0313 
0314 /// True iff the specified type index is a scalar or a vector with an element
0315 /// type that's wider than the given size.
0316 LegalityPredicate scalarOrEltWiderThan(unsigned TypeIdx, unsigned Size);
0317 
0318 /// True iff the specified type index is a scalar whose size is not a multiple
0319 /// of Size.
0320 LegalityPredicate sizeNotMultipleOf(unsigned TypeIdx, unsigned Size);
0321 
0322 /// True iff the specified type index is a scalar whose size is not a power of
0323 /// 2.
0324 LegalityPredicate sizeNotPow2(unsigned TypeIdx);
0325 
0326 /// True iff the specified type index is a scalar or vector whose element size
0327 /// is not a power of 2.
0328 LegalityPredicate scalarOrEltSizeNotPow2(unsigned TypeIdx);
0329 
0330 /// True if the total bitwidth of the specified type index is \p Size bits.
0331 LegalityPredicate sizeIs(unsigned TypeIdx, unsigned Size);
0332 
0333 /// True iff the specified type indices are both the same bit size.
0334 LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1);
0335 
0336 /// True iff the first type index has a larger total bit size than second type
0337 /// index.
0338 LegalityPredicate largerThan(unsigned TypeIdx0, unsigned TypeIdx1);
0339 
0340 /// True iff the first type index has a smaller total bit size than second type
0341 /// index.
0342 LegalityPredicate smallerThan(unsigned TypeIdx0, unsigned TypeIdx1);
0343 
0344 /// True iff the specified MMO index has a size (rounded to bytes) that is not a
0345 /// power of 2.
0346 LegalityPredicate memSizeInBytesNotPow2(unsigned MMOIdx);
0347 
0348 /// True iff the specified MMO index has a size that is not an even byte size,
0349 /// or that even byte size is not a power of 2.
0350 LegalityPredicate memSizeNotByteSizePow2(unsigned MMOIdx);
0351 
0352 /// True iff the specified type index is a vector whose element count is not a
0353 /// power of 2.
0354 LegalityPredicate numElementsNotPow2(unsigned TypeIdx);
0355 /// True iff the specified MMO index has at an atomic ordering of at Ordering or
0356 /// stronger.
0357 LegalityPredicate atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx,
0358                                                       AtomicOrdering Ordering);
0359 } // end namespace LegalityPredicates
0360 
0361 namespace LegalizeMutations {
0362 /// Select this specific type for the given type index.
0363 LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
0364 
0365 /// Keep the same type as the given type index.
0366 LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx);
0367 
0368 /// Keep the same scalar or element type as the given type index.
0369 LegalizeMutation changeElementTo(unsigned TypeIdx, unsigned FromTypeIdx);
0370 
0371 /// Keep the same scalar or element type as the given type.
0372 LegalizeMutation changeElementTo(unsigned TypeIdx, LLT Ty);
0373 
0374 /// Keep the same scalar or element type as \p TypeIdx, but take the number of
0375 /// elements from \p FromTypeIdx.
0376 LegalizeMutation changeElementCountTo(unsigned TypeIdx, unsigned FromTypeIdx);
0377 
0378 /// Keep the same scalar or element type as \p TypeIdx, but take the number of
0379 /// elements from \p Ty.
0380 LegalizeMutation changeElementCountTo(unsigned TypeIdx, LLT Ty);
0381 
0382 /// Change the scalar size or element size to have the same scalar size as type
0383 /// index \p FromIndex. Unlike changeElementTo, this discards pointer types and
0384 /// only changes the size.
0385 LegalizeMutation changeElementSizeTo(unsigned TypeIdx, unsigned FromTypeIdx);
0386 
0387 /// Widen the scalar type or vector element type for the given type index to the
0388 /// next power of 2.
0389 LegalizeMutation widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned Min = 0);
0390 
0391 /// Widen the scalar type or vector element type for the given type index to
0392 /// next multiple of \p Size.
0393 LegalizeMutation widenScalarOrEltToNextMultipleOf(unsigned TypeIdx,
0394                                                   unsigned Size);
0395 
0396 /// Add more elements to the type for the given type index to the next power of
0397 /// 2.
0398 LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min = 0);
0399 /// Break up the vector type for the given type index into the element type.
0400 LegalizeMutation scalarize(unsigned TypeIdx);
0401 } // end namespace LegalizeMutations
0402 
0403 /// A single rule in a legalizer info ruleset.
0404 /// The specified action is chosen when the predicate is true. Where appropriate
0405 /// for the action (e.g. for WidenScalar) the new type is selected using the
0406 /// given mutator.
0407 class LegalizeRule {
0408   LegalityPredicate Predicate;
0409   LegalizeAction Action;
0410   LegalizeMutation Mutation;
0411 
0412 public:
0413   LegalizeRule(LegalityPredicate Predicate, LegalizeAction Action,
0414                LegalizeMutation Mutation = nullptr)
0415       : Predicate(Predicate), Action(Action), Mutation(Mutation) {}
0416 
0417   /// Test whether the LegalityQuery matches.
0418   bool match(const LegalityQuery &Query) const {
0419     return Predicate(Query);
0420   }
0421 
0422   LegalizeAction getAction() const { return Action; }
0423 
0424   /// Determine the change to make.
0425   std::pair<unsigned, LLT> determineMutation(const LegalityQuery &Query) const {
0426     if (Mutation)
0427       return Mutation(Query);
0428     return std::make_pair(0, LLT{});
0429   }
0430 };
0431 
0432 class LegalizeRuleSet {
0433   /// When non-zero, the opcode we are an alias of
0434   unsigned AliasOf = 0;
0435   /// If true, there is another opcode that aliases this one
0436   bool IsAliasedByAnother = false;
0437   SmallVector<LegalizeRule, 2> Rules;
0438 
0439 #ifndef NDEBUG
0440   /// If bit I is set, this rule set contains a rule that may handle (predicate
0441   /// or perform an action upon (or both)) the type index I. The uncertainty
0442   /// comes from free-form rules executing user-provided lambda functions. We
0443   /// conservatively assume such rules do the right thing and cover all type
0444   /// indices. The bitset is intentionally 1 bit wider than it absolutely needs
0445   /// to be to distinguish such cases from the cases where all type indices are
0446   /// individually handled.
0447   SmallBitVector TypeIdxsCovered{MCOI::OPERAND_LAST_GENERIC -
0448                                  MCOI::OPERAND_FIRST_GENERIC + 2};
0449   SmallBitVector ImmIdxsCovered{MCOI::OPERAND_LAST_GENERIC_IMM -
0450                                 MCOI::OPERAND_FIRST_GENERIC_IMM + 2};
0451 #endif
0452 
0453   unsigned typeIdx(unsigned TypeIdx) {
0454     assert(TypeIdx <=
0455                (MCOI::OPERAND_LAST_GENERIC - MCOI::OPERAND_FIRST_GENERIC) &&
0456            "Type Index is out of bounds");
0457 #ifndef NDEBUG
0458     TypeIdxsCovered.set(TypeIdx);
0459 #endif
0460     return TypeIdx;
0461   }
0462 
0463   void markAllIdxsAsCovered() {
0464 #ifndef NDEBUG
0465     TypeIdxsCovered.set();
0466     ImmIdxsCovered.set();
0467 #endif
0468   }
0469 
0470   void add(const LegalizeRule &Rule) {
0471     assert(AliasOf == 0 &&
0472            "RuleSet is aliased, change the representative opcode instead");
0473     Rules.push_back(Rule);
0474   }
0475 
0476   static bool always(const LegalityQuery &) { return true; }
0477 
0478   /// Use the given action when the predicate is true.
0479   /// Action should not be an action that requires mutation.
0480   LegalizeRuleSet &actionIf(LegalizeAction Action,
0481                             LegalityPredicate Predicate) {
0482     add({Predicate, Action});
0483     return *this;
0484   }
0485   /// Use the given action when the predicate is true.
0486   /// Action should be an action that requires mutation.
0487   LegalizeRuleSet &actionIf(LegalizeAction Action, LegalityPredicate Predicate,
0488                             LegalizeMutation Mutation) {
0489     add({Predicate, Action, Mutation});
0490     return *this;
0491   }
0492   /// Use the given action when type index 0 is any type in the given list.
0493   /// Action should not be an action that requires mutation.
0494   LegalizeRuleSet &actionFor(LegalizeAction Action,
0495                              std::initializer_list<LLT> Types) {
0496     using namespace LegalityPredicates;
0497     return actionIf(Action, typeInSet(typeIdx(0), Types));
0498   }
0499   /// Use the given action when type index 0 is any type in the given list.
0500   /// Action should be an action that requires mutation.
0501   LegalizeRuleSet &actionFor(LegalizeAction Action,
0502                              std::initializer_list<LLT> Types,
0503                              LegalizeMutation Mutation) {
0504     using namespace LegalityPredicates;
0505     return actionIf(Action, typeInSet(typeIdx(0), Types), Mutation);
0506   }
0507   /// Use the given action when type indexes 0 and 1 is any type pair in the
0508   /// given list.
0509   /// Action should not be an action that requires mutation.
0510   LegalizeRuleSet &actionFor(LegalizeAction Action,
0511                              std::initializer_list<std::pair<LLT, LLT>> Types) {
0512     using namespace LegalityPredicates;
0513     return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
0514   }
0515 
0516   LegalizeRuleSet &
0517   actionFor(LegalizeAction Action,
0518             std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
0519     using namespace LegalityPredicates;
0520     return actionIf(Action,
0521                     typeTupleInSet(typeIdx(0), typeIdx(1), typeIdx(2), Types));
0522   }
0523 
0524   /// Use the given action when type indexes 0 and 1 is any type pair in the
0525   /// given list.
0526   /// Action should be an action that requires mutation.
0527   LegalizeRuleSet &actionFor(LegalizeAction Action,
0528                              std::initializer_list<std::pair<LLT, LLT>> Types,
0529                              LegalizeMutation Mutation) {
0530     using namespace LegalityPredicates;
0531     return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types),
0532                     Mutation);
0533   }
0534   /// Use the given action when type index 0 is any type in the given list and
0535   /// imm index 0 is anything. Action should not be an action that requires
0536   /// mutation.
0537   LegalizeRuleSet &actionForTypeWithAnyImm(LegalizeAction Action,
0538                                            std::initializer_list<LLT> Types) {
0539     using namespace LegalityPredicates;
0540     immIdx(0); // Inform verifier imm idx 0 is handled.
0541     return actionIf(Action, typeInSet(typeIdx(0), Types));
0542   }
0543 
0544   LegalizeRuleSet &actionForTypeWithAnyImm(
0545     LegalizeAction Action, std::initializer_list<std::pair<LLT, LLT>> Types) {
0546     using namespace LegalityPredicates;
0547     immIdx(0); // Inform verifier imm idx 0 is handled.
0548     return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
0549   }
0550 
0551   /// Use the given action when type indexes 0 and 1 are both in the given list.
0552   /// That is, the type pair is in the cartesian product of the list.
0553   /// Action should not be an action that requires mutation.
0554   LegalizeRuleSet &actionForCartesianProduct(LegalizeAction Action,
0555                                              std::initializer_list<LLT> Types) {
0556     using namespace LegalityPredicates;
0557     return actionIf(Action, all(typeInSet(typeIdx(0), Types),
0558                                 typeInSet(typeIdx(1), Types)));
0559   }
0560   /// Use the given action when type indexes 0 and 1 are both in their
0561   /// respective lists.
0562   /// That is, the type pair is in the cartesian product of the lists
0563   /// Action should not be an action that requires mutation.
0564   LegalizeRuleSet &
0565   actionForCartesianProduct(LegalizeAction Action,
0566                             std::initializer_list<LLT> Types0,
0567                             std::initializer_list<LLT> Types1) {
0568     using namespace LegalityPredicates;
0569     return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
0570                                 typeInSet(typeIdx(1), Types1)));
0571   }
0572   /// Use the given action when type indexes 0, 1, and 2 are all in their
0573   /// respective lists.
0574   /// That is, the type triple is in the cartesian product of the lists
0575   /// Action should not be an action that requires mutation.
0576   LegalizeRuleSet &actionForCartesianProduct(
0577       LegalizeAction Action, std::initializer_list<LLT> Types0,
0578       std::initializer_list<LLT> Types1, std::initializer_list<LLT> Types2) {
0579     using namespace LegalityPredicates;
0580     return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
0581                                 all(typeInSet(typeIdx(1), Types1),
0582                                     typeInSet(typeIdx(2), Types2))));
0583   }
0584 
0585 public:
0586   LegalizeRuleSet() = default;
0587 
0588   bool isAliasedByAnother() { return IsAliasedByAnother; }
0589   void setIsAliasedByAnother() { IsAliasedByAnother = true; }
0590   void aliasTo(unsigned Opcode) {
0591     assert((AliasOf == 0 || AliasOf == Opcode) &&
0592            "Opcode is already aliased to another opcode");
0593     assert(Rules.empty() && "Aliasing will discard rules");
0594     AliasOf = Opcode;
0595   }
0596   unsigned getAlias() const { return AliasOf; }
0597 
0598   unsigned immIdx(unsigned ImmIdx) {
0599     assert(ImmIdx <= (MCOI::OPERAND_LAST_GENERIC_IMM -
0600                       MCOI::OPERAND_FIRST_GENERIC_IMM) &&
0601            "Imm Index is out of bounds");
0602 #ifndef NDEBUG
0603     ImmIdxsCovered.set(ImmIdx);
0604 #endif
0605     return ImmIdx;
0606   }
0607 
0608   /// The instruction is legal if predicate is true.
0609   LegalizeRuleSet &legalIf(LegalityPredicate Predicate) {
0610     // We have no choice but conservatively assume that the free-form
0611     // user-provided Predicate properly handles all type indices:
0612     markAllIdxsAsCovered();
0613     return actionIf(LegalizeAction::Legal, Predicate);
0614   }
0615   /// The instruction is legal when type index 0 is any type in the given list.
0616   LegalizeRuleSet &legalFor(std::initializer_list<LLT> Types) {
0617     return actionFor(LegalizeAction::Legal, Types);
0618   }
0619   LegalizeRuleSet &legalFor(bool Pred, std::initializer_list<LLT> Types) {
0620     if (!Pred)
0621       return *this;
0622     return actionFor(LegalizeAction::Legal, Types);
0623   }
0624   /// The instruction is legal when type indexes 0 and 1 is any type pair in the
0625   /// given list.
0626   LegalizeRuleSet &legalFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
0627     return actionFor(LegalizeAction::Legal, Types);
0628   }
0629   LegalizeRuleSet &legalFor(bool Pred,
0630                             std::initializer_list<std::pair<LLT, LLT>> Types) {
0631     if (!Pred)
0632       return *this;
0633     return actionFor(LegalizeAction::Legal, Types);
0634   }
0635   LegalizeRuleSet &
0636   legalFor(bool Pred, std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
0637     if (!Pred)
0638       return *this;
0639     return actionFor(LegalizeAction::Legal, Types);
0640   }
0641   /// The instruction is legal when type index 0 is any type in the given list
0642   /// and imm index 0 is anything.
0643   LegalizeRuleSet &legalForTypeWithAnyImm(std::initializer_list<LLT> Types) {
0644     markAllIdxsAsCovered();
0645     return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
0646   }
0647 
0648   LegalizeRuleSet &legalForTypeWithAnyImm(
0649     std::initializer_list<std::pair<LLT, LLT>> Types) {
0650     markAllIdxsAsCovered();
0651     return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
0652   }
0653 
0654   /// The instruction is legal when type indexes 0 and 1 along with the memory
0655   /// size and minimum alignment is any type and size tuple in the given list.
0656   LegalizeRuleSet &legalForTypesWithMemDesc(
0657       std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
0658           TypesAndMemDesc) {
0659     return actionIf(LegalizeAction::Legal,
0660                     LegalityPredicates::typePairAndMemDescInSet(
0661                         typeIdx(0), typeIdx(1), /*MMOIdx*/ 0, TypesAndMemDesc));
0662   }
0663   /// The instruction is legal when type indexes 0 and 1 are both in the given
0664   /// list. That is, the type pair is in the cartesian product of the list.
0665   LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types) {
0666     return actionForCartesianProduct(LegalizeAction::Legal, Types);
0667   }
0668   /// The instruction is legal when type indexes 0 and 1 are both their
0669   /// respective lists.
0670   LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
0671                                             std::initializer_list<LLT> Types1) {
0672     return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
0673   }
0674   /// The instruction is legal when type indexes 0, 1, and 2 are both their
0675   /// respective lists.
0676   LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
0677                                             std::initializer_list<LLT> Types1,
0678                                             std::initializer_list<LLT> Types2) {
0679     return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1,
0680                                      Types2);
0681   }
0682 
0683   LegalizeRuleSet &alwaysLegal() {
0684     using namespace LegalizeMutations;
0685     markAllIdxsAsCovered();
0686     return actionIf(LegalizeAction::Legal, always);
0687   }
0688 
0689   /// The specified type index is coerced if predicate is true.
0690   LegalizeRuleSet &bitcastIf(LegalityPredicate Predicate,
0691                              LegalizeMutation Mutation) {
0692     // We have no choice but conservatively assume that lowering with a
0693     // free-form user provided Predicate properly handles all type indices:
0694     markAllIdxsAsCovered();
0695     return actionIf(LegalizeAction::Bitcast, Predicate, Mutation);
0696   }
0697 
0698   /// The instruction is lowered.
0699   LegalizeRuleSet &lower() {
0700     using namespace LegalizeMutations;
0701     // We have no choice but conservatively assume that predicate-less lowering
0702     // properly handles all type indices by design:
0703     markAllIdxsAsCovered();
0704     return actionIf(LegalizeAction::Lower, always);
0705   }
0706   /// The instruction is lowered if predicate is true. Keep type index 0 as the
0707   /// same type.
0708   LegalizeRuleSet &lowerIf(LegalityPredicate Predicate) {
0709     using namespace LegalizeMutations;
0710     // We have no choice but conservatively assume that lowering with a
0711     // free-form user provided Predicate properly handles all type indices:
0712     markAllIdxsAsCovered();
0713     return actionIf(LegalizeAction::Lower, Predicate);
0714   }
0715   /// The instruction is lowered if predicate is true.
0716   LegalizeRuleSet &lowerIf(LegalityPredicate Predicate,
0717                            LegalizeMutation Mutation) {
0718     // We have no choice but conservatively assume that lowering with a
0719     // free-form user provided Predicate properly handles all type indices:
0720     markAllIdxsAsCovered();
0721     return actionIf(LegalizeAction::Lower, Predicate, Mutation);
0722   }
0723   /// The instruction is lowered when type index 0 is any type in the given
0724   /// list. Keep type index 0 as the same type.
0725   LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types) {
0726     return actionFor(LegalizeAction::Lower, Types);
0727   }
0728   /// The instruction is lowered when type index 0 is any type in the given
0729   /// list.
0730   LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types,
0731                             LegalizeMutation Mutation) {
0732     return actionFor(LegalizeAction::Lower, Types, Mutation);
0733   }
0734   /// The instruction is lowered when type indexes 0 and 1 is any type pair in
0735   /// the given list. Keep type index 0 as the same type.
0736   LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
0737     return actionFor(LegalizeAction::Lower, Types);
0738   }
0739   /// The instruction is lowered when type indexes 0 and 1 is any type pair in
0740   /// the given list.
0741   LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types,
0742                             LegalizeMutation Mutation) {
0743     return actionFor(LegalizeAction::Lower, Types, Mutation);
0744   }
0745   /// The instruction is lowered when type indexes 0 and 1 are both in their
0746   /// respective lists.
0747   LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
0748                                             std::initializer_list<LLT> Types1) {
0749     using namespace LegalityPredicates;
0750     return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1);
0751   }
0752   /// The instruction is lowered when type indexes 0, 1, and 2 are all in
0753   /// their respective lists.
0754   LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
0755                                             std::initializer_list<LLT> Types1,
0756                                             std::initializer_list<LLT> Types2) {
0757     using namespace LegalityPredicates;
0758     return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1,
0759                                      Types2);
0760   }
0761 
0762   /// The instruction is emitted as a library call.
0763   LegalizeRuleSet &libcall() {
0764     using namespace LegalizeMutations;
0765     // We have no choice but conservatively assume that predicate-less lowering
0766     // properly handles all type indices by design:
0767     markAllIdxsAsCovered();
0768     return actionIf(LegalizeAction::Libcall, always);
0769   }
0770 
0771   /// Like legalIf, but for the Libcall action.
0772   LegalizeRuleSet &libcallIf(LegalityPredicate Predicate) {
0773     // We have no choice but conservatively assume that a libcall with a
0774     // free-form user provided Predicate properly handles all type indices:
0775     markAllIdxsAsCovered();
0776     return actionIf(LegalizeAction::Libcall, Predicate);
0777   }
0778   LegalizeRuleSet &libcallFor(std::initializer_list<LLT> Types) {
0779     return actionFor(LegalizeAction::Libcall, Types);
0780   }
0781   LegalizeRuleSet &libcallFor(bool Pred, std::initializer_list<LLT> Types) {
0782     if (!Pred)
0783       return *this;
0784     return actionFor(LegalizeAction::Libcall, Types);
0785   }
0786   LegalizeRuleSet &
0787   libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
0788     return actionFor(LegalizeAction::Libcall, Types);
0789   }
0790   LegalizeRuleSet &
0791   libcallFor(bool Pred, std::initializer_list<std::pair<LLT, LLT>> Types) {
0792     if (!Pred)
0793       return *this;
0794     return actionFor(LegalizeAction::Libcall, Types);
0795   }
0796   LegalizeRuleSet &
0797   libcallForCartesianProduct(std::initializer_list<LLT> Types) {
0798     return actionForCartesianProduct(LegalizeAction::Libcall, Types);
0799   }
0800   LegalizeRuleSet &
0801   libcallForCartesianProduct(std::initializer_list<LLT> Types0,
0802                              std::initializer_list<LLT> Types1) {
0803     return actionForCartesianProduct(LegalizeAction::Libcall, Types0, Types1);
0804   }
0805 
0806   /// Widen the scalar to the one selected by the mutation if the predicate is
0807   /// true.
0808   LegalizeRuleSet &widenScalarIf(LegalityPredicate Predicate,
0809                                  LegalizeMutation Mutation) {
0810     // We have no choice but conservatively assume that an action with a
0811     // free-form user provided Predicate properly handles all type indices:
0812     markAllIdxsAsCovered();
0813     return actionIf(LegalizeAction::WidenScalar, Predicate, Mutation);
0814   }
0815   /// Narrow the scalar to the one selected by the mutation if the predicate is
0816   /// true.
0817   LegalizeRuleSet &narrowScalarIf(LegalityPredicate Predicate,
0818                                   LegalizeMutation Mutation) {
0819     // We have no choice but conservatively assume that an action with a
0820     // free-form user provided Predicate properly handles all type indices:
0821     markAllIdxsAsCovered();
0822     return actionIf(LegalizeAction::NarrowScalar, Predicate, Mutation);
0823   }
0824   /// Narrow the scalar, specified in mutation, when type indexes 0 and 1 is any
0825   /// type pair in the given list.
0826   LegalizeRuleSet &
0827   narrowScalarFor(std::initializer_list<std::pair<LLT, LLT>> Types,
0828                   LegalizeMutation Mutation) {
0829     return actionFor(LegalizeAction::NarrowScalar, Types, Mutation);
0830   }
0831 
0832   /// Add more elements to reach the type selected by the mutation if the
0833   /// predicate is true.
0834   LegalizeRuleSet &moreElementsIf(LegalityPredicate Predicate,
0835                                   LegalizeMutation Mutation) {
0836     // We have no choice but conservatively assume that an action with a
0837     // free-form user provided Predicate properly handles all type indices:
0838     markAllIdxsAsCovered();
0839     return actionIf(LegalizeAction::MoreElements, Predicate, Mutation);
0840   }
0841   /// Remove elements to reach the type selected by the mutation if the
0842   /// predicate is true.
0843   LegalizeRuleSet &fewerElementsIf(LegalityPredicate Predicate,
0844                                    LegalizeMutation Mutation) {
0845     // We have no choice but conservatively assume that an action with a
0846     // free-form user provided Predicate properly handles all type indices:
0847     markAllIdxsAsCovered();
0848     return actionIf(LegalizeAction::FewerElements, Predicate, Mutation);
0849   }
0850 
0851   /// The instruction is unsupported.
0852   LegalizeRuleSet &unsupported() {
0853     markAllIdxsAsCovered();
0854     return actionIf(LegalizeAction::Unsupported, always);
0855   }
0856   LegalizeRuleSet &unsupportedIf(LegalityPredicate Predicate) {
0857     return actionIf(LegalizeAction::Unsupported, Predicate);
0858   }
0859 
0860   LegalizeRuleSet &unsupportedFor(std::initializer_list<LLT> Types) {
0861     return actionFor(LegalizeAction::Unsupported, Types);
0862   }
0863 
0864   LegalizeRuleSet &unsupportedIfMemSizeNotPow2() {
0865     return actionIf(LegalizeAction::Unsupported,
0866                     LegalityPredicates::memSizeInBytesNotPow2(0));
0867   }
0868 
0869   /// Lower a memory operation if the memory size, rounded to bytes, is not a
0870   /// power of 2. For example, this will not trigger for s1 or s7, but will for
0871   /// s24.
0872   LegalizeRuleSet &lowerIfMemSizeNotPow2() {
0873     return actionIf(LegalizeAction::Lower,
0874                     LegalityPredicates::memSizeInBytesNotPow2(0));
0875   }
0876 
0877   /// Lower a memory operation if the memory access size is not a round power of
0878   /// 2 byte size. This is stricter than lowerIfMemSizeNotPow2, and more likely
0879   /// what you want (e.g. this will lower s1, s7 and s24).
0880   LegalizeRuleSet &lowerIfMemSizeNotByteSizePow2() {
0881     return actionIf(LegalizeAction::Lower,
0882                     LegalityPredicates::memSizeNotByteSizePow2(0));
0883   }
0884 
0885   LegalizeRuleSet &customIf(LegalityPredicate Predicate) {
0886     // We have no choice but conservatively assume that a custom action with a
0887     // free-form user provided Predicate properly handles all type indices:
0888     markAllIdxsAsCovered();
0889     return actionIf(LegalizeAction::Custom, Predicate);
0890   }
0891   LegalizeRuleSet &customFor(std::initializer_list<LLT> Types) {
0892     return actionFor(LegalizeAction::Custom, Types);
0893   }
0894   LegalizeRuleSet &customFor(bool Pred, std::initializer_list<LLT> Types) {
0895     if (!Pred)
0896       return *this;
0897     return actionFor(LegalizeAction::Custom, Types);
0898   }
0899 
0900   /// The instruction is custom when type indexes 0 and 1 is any type pair in
0901   /// the given list.
0902   LegalizeRuleSet &customFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
0903     return actionFor(LegalizeAction::Custom, Types);
0904   }
0905   LegalizeRuleSet &customFor(bool Pred,
0906                              std::initializer_list<std::pair<LLT, LLT>> Types) {
0907     if (!Pred)
0908       return *this;
0909     return actionFor(LegalizeAction::Custom, Types);
0910   }
0911 
0912   LegalizeRuleSet &customForCartesianProduct(std::initializer_list<LLT> Types) {
0913     return actionForCartesianProduct(LegalizeAction::Custom, Types);
0914   }
0915   /// The instruction is custom when type indexes 0 and 1 are both in their
0916   /// respective lists.
0917   LegalizeRuleSet &
0918   customForCartesianProduct(std::initializer_list<LLT> Types0,
0919                             std::initializer_list<LLT> Types1) {
0920     return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
0921   }
0922   /// The instruction is custom when type indexes 0, 1, and 2 are all in
0923   /// their respective lists.
0924   LegalizeRuleSet &
0925   customForCartesianProduct(std::initializer_list<LLT> Types0,
0926                             std::initializer_list<LLT> Types1,
0927                             std::initializer_list<LLT> Types2) {
0928     return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1,
0929                                      Types2);
0930   }
0931 
0932   /// Unconditionally custom lower.
0933   LegalizeRuleSet &custom() {
0934     return customIf(always);
0935   }
0936 
0937   /// Widen the scalar to the next power of two that is at least MinSize.
0938   /// No effect if the type is a power of two, except if the type is smaller
0939   /// than MinSize, or if the type is a vector type.
0940   LegalizeRuleSet &widenScalarToNextPow2(unsigned TypeIdx,
0941                                          unsigned MinSize = 0) {
0942     using namespace LegalityPredicates;
0943     return actionIf(
0944         LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
0945         LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize));
0946   }
0947 
0948   /// Widen the scalar to the next multiple of Size. No effect if the
0949   /// type is not a scalar or is a multiple of Size.
0950   LegalizeRuleSet &widenScalarToNextMultipleOf(unsigned TypeIdx,
0951                                                unsigned Size) {
0952     using namespace LegalityPredicates;
0953     return actionIf(
0954         LegalizeAction::WidenScalar, sizeNotMultipleOf(typeIdx(TypeIdx), Size),
0955         LegalizeMutations::widenScalarOrEltToNextMultipleOf(TypeIdx, Size));
0956   }
0957 
0958   /// Widen the scalar or vector element type to the next power of two that is
0959   /// at least MinSize.  No effect if the scalar size is a power of two.
0960   LegalizeRuleSet &widenScalarOrEltToNextPow2(unsigned TypeIdx,
0961                                               unsigned MinSize = 0) {
0962     using namespace LegalityPredicates;
0963     return actionIf(
0964         LegalizeAction::WidenScalar, scalarOrEltSizeNotPow2(typeIdx(TypeIdx)),
0965         LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize));
0966   }
0967 
0968   /// Widen the scalar or vector element type to the next power of two that is
0969   /// at least MinSize.  No effect if the scalar size is a power of two.
0970   LegalizeRuleSet &widenScalarOrEltToNextPow2OrMinSize(unsigned TypeIdx,
0971                                                        unsigned MinSize = 0) {
0972     using namespace LegalityPredicates;
0973     return actionIf(
0974         LegalizeAction::WidenScalar,
0975         any(scalarOrEltNarrowerThan(TypeIdx, MinSize),
0976             scalarOrEltSizeNotPow2(typeIdx(TypeIdx))),
0977         LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize));
0978   }
0979 
0980   LegalizeRuleSet &narrowScalar(unsigned TypeIdx, LegalizeMutation Mutation) {
0981     using namespace LegalityPredicates;
0982     return actionIf(LegalizeAction::NarrowScalar, isScalar(typeIdx(TypeIdx)),
0983                     Mutation);
0984   }
0985 
0986   LegalizeRuleSet &scalarize(unsigned TypeIdx) {
0987     using namespace LegalityPredicates;
0988     return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)),
0989                     LegalizeMutations::scalarize(TypeIdx));
0990   }
0991 
0992   LegalizeRuleSet &scalarizeIf(LegalityPredicate Predicate, unsigned TypeIdx) {
0993     using namespace LegalityPredicates;
0994     return actionIf(LegalizeAction::FewerElements,
0995                     all(Predicate, isVector(typeIdx(TypeIdx))),
0996                     LegalizeMutations::scalarize(TypeIdx));
0997   }
0998 
0999   /// 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