diff options
6 files changed, 171 insertions, 84 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h index 7252fedac9e..9252dd94f0d 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h @@ -60,20 +60,22 @@ public: /// Legalize an instruction by reducing the width of the underlying scalar /// type. - LegalizeResult narrowScalar(MachineInstr &MI, LLT NarrowTy); + LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy); /// Legalize an instruction by performing the operation on a wider scalar type /// (for example a 16-bit addition can be safely performed at 32-bits /// precision, ignoring the unused bits). - LegalizeResult widenScalar(MachineInstr &MI, LLT WideTy); + LegalizeResult widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); /// Legalize a vector instruction by splitting into multiple components, each /// acting on the same scalar type as the original but with fewer elements. - LegalizeResult fewerElementsVector(MachineInstr &MI, LLT NarrowTy); + LegalizeResult fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, + LLT NarrowTy); /// Legalize a vector instruction by increasing the number of vector elements /// involved and ignoring the added elements later. - LegalizeResult moreElementsVector(MachineInstr &MI, LLT WideTy); + LegalizeResult moreElementsVector(MachineInstr &MI, unsigned TypeIdx, + LLT WideTy); private: diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h index 29398e87207..439f2aeae40 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h @@ -27,6 +27,38 @@ class MachineInstr; class Type; class VectorType; +/// Legalization is decided based on an instruction's opcode, which type slot +/// we're considering, and what the existing type is. These aspects are gathered +/// together for convenience in the InstrAspect class. +struct InstrAspect { + unsigned Opcode; + unsigned Idx; + LLT Type; + + InstrAspect(unsigned Opcode, LLT Type) : Opcode(Opcode), Idx(0), Type(Type) {} + InstrAspect(unsigned Opcode, unsigned Idx, LLT Type) + : Opcode(Opcode), Idx(Idx), Type(Type) {} + + bool operator==(const InstrAspect &RHS) const { + return Opcode == RHS.Opcode && Idx == RHS.Idx && Type == RHS.Type; + } +}; + +template <> struct DenseMapInfo<InstrAspect> { + static inline InstrAspect getEmptyKey() { return {-1u, 0, LLT{}}; } + + static inline InstrAspect getTombstoneKey() { return {-2u, 0, LLT{}}; } + + static unsigned getHashValue(const InstrAspect &Val) { + return DenseMapInfo<std::pair<uint64_t, LLT>>::getHashValue( + {(uint64_t)Val.Opcode << 32 | Val.Idx, Val.Type}); + } + + static bool isEqual(const InstrAspect &LHS, const InstrAspect &RHS) { + return LHS == RHS; + } +}; + class MachineLegalizer { public: enum LegalizeAction : std::uint8_t { @@ -78,9 +110,9 @@ public: /// More friendly way to set an action for common types that have an LLT /// representation. - void setAction(unsigned Opcode, LLT Ty, LegalizeAction Action) { + void setAction(const InstrAspect &Aspect, LegalizeAction Action) { TablesInitialized = false; - Actions[std::make_pair(Opcode, Ty)] = Action; + Actions[Aspect] = Action; } /// If an operation on a given vector type (say <M x iN>) isn't explicitly @@ -96,23 +128,32 @@ public: /// Determine what action should be taken to legalize the given generic - /// instruction and type. Requires computeTables to have been called. + /// instruction opcode, type-index and type. Requires computeTables to have + /// been called. /// /// \returns a pair consisting of the kind of legalization that should be /// performed and the destination type. - std::pair<LegalizeAction, LLT> getAction(unsigned Opcode, LLT) const; - std::pair<LegalizeAction, LLT> getAction(const MachineInstr &MI) const; + std::pair<LegalizeAction, LLT> getAction(const InstrAspect &Aspect) const; + + /// Determine what action should be taken to legalize the given generic instruction. + /// + /// \returns a tuple consisting of the LegalizeAction that should be + /// performed, the type-index it should be performed on and the destination + /// type. + std::tuple<LegalizeAction, unsigned, LLT> + getAction(const MachineInstr &MI) const; /// Iterate the given function (typically something like doubling the width) /// on Ty until we find a legal type for this operation. - LLT findLegalType(unsigned Opcode, LLT Ty, - std::function<LLT(LLT)> NextType) const { + LLT findLegalType(const InstrAspect &Aspect, + std::function<LLT(LLT)> NextType) const { LegalizeAction Action; + LLT Ty = Aspect.Type; do { Ty = NextType(Ty); - auto ActionIt = Actions.find(std::make_pair(Opcode, Ty)); + auto ActionIt = Actions.find({Aspect.Opcode, Aspect.Idx, Ty}); if (ActionIt == Actions.end()) - Action = DefaultActions.find(Opcode)->second; + Action = DefaultActions.find(Aspect.Opcode)->second; else Action = ActionIt->second; } while(Action != Legal); @@ -121,26 +162,28 @@ public: /// Find what type it's actually OK to perform the given operation on, given /// the general approach we've decided to take. - LLT findLegalType(unsigned Opcode, LLT Ty, LegalizeAction Action) const; + LLT findLegalType(const InstrAspect &Aspect, LegalizeAction Action) const; - std::pair<LegalizeAction, LLT> findLegalAction(unsigned Opcode, LLT Ty, + std::pair<LegalizeAction, LLT> findLegalAction(const InstrAspect &Aspect, LegalizeAction Action) const { - return std::make_pair(Action, findLegalType(Opcode, Ty, Action)); + return std::make_pair(Action, findLegalType(Aspect, Action)); } bool isLegal(const MachineInstr &MI) const; private: - typedef DenseMap<std::pair<unsigned, LLT>, LegalizeAction> ActionMap; + typedef DenseMap<InstrAspect, LegalizeAction> ActionMap; + typedef DenseMap<std::pair<unsigned, LLT>, LegalizeAction> SIVActionMap; ActionMap Actions; - ActionMap ScalarInVectorActions; + SIVActionMap ScalarInVectorActions; DenseMap<std::pair<unsigned, LLT>, uint16_t> MaxLegalVectorElts; DenseMap<unsigned, LegalizeAction> DefaultActions; bool TablesInitialized; }; + } // End namespace llvm. #endif diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp index 7c3253dd36a..bd8374cb6b0 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp @@ -34,15 +34,15 @@ MachineLegalizeHelper::MachineLegalizeHelper(MachineFunction &MF) MachineLegalizeHelper::LegalizeResult MachineLegalizeHelper::legalizeInstr( MachineInstr &MI, const MachineLegalizer &Legalizer) { auto Action = Legalizer.getAction(MI); - switch (Action.first) { + switch (std::get<0>(Action)) { case MachineLegalizer::Legal: return AlreadyLegal; case MachineLegalizer::NarrowScalar: - return narrowScalar(MI, Action.second); + return narrowScalar(MI, std::get<1>(Action), std::get<2>(Action)); case MachineLegalizer::WidenScalar: - return widenScalar(MI, Action.second); + return widenScalar(MI, std::get<1>(Action), std::get<2>(Action)); case MachineLegalizer::FewerElements: - return fewerElementsVector(MI, Action.second); + return fewerElementsVector(MI, std::get<1>(Action), std::get<2>(Action)); default: return UnableToLegalize; } @@ -63,7 +63,9 @@ void MachineLegalizeHelper::extractParts(unsigned Reg, LLT Ty, int NumParts, } MachineLegalizeHelper::LegalizeResult -MachineLegalizeHelper::narrowScalar(MachineInstr &MI, LLT NarrowTy) { +MachineLegalizeHelper::narrowScalar(MachineInstr &MI, unsigned TypeIdx, + LLT NarrowTy) { + assert(TypeIdx == 0 && "don't know how to handle secondary types yet"); switch (MI.getOpcode()) { default: return UnableToLegalize; @@ -103,7 +105,10 @@ MachineLegalizeHelper::narrowScalar(MachineInstr &MI, LLT NarrowTy) { } MachineLegalizeHelper::LegalizeResult -MachineLegalizeHelper::widenScalar(MachineInstr &MI, LLT WideTy) { +MachineLegalizeHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, + LLT WideTy) { + assert(TypeIdx == 0 && "don't know how to handle secondary types yet"); + unsigned WideSize = WideTy.getSizeInBits(); MIRBuilder.setInstr(MI); @@ -172,7 +177,9 @@ MachineLegalizeHelper::widenScalar(MachineInstr &MI, LLT WideTy) { } MachineLegalizeHelper::LegalizeResult -MachineLegalizeHelper::fewerElementsVector(MachineInstr &MI, LLT NarrowTy) { +MachineLegalizeHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, + LLT NarrowTy) { + assert(TypeIdx == 0 && "don't know how to handle secondary types yet"); switch (MI.getOpcode()) { default: return UnableToLegalize; diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp index fa23627de7c..dd32b1fe10f 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp @@ -35,12 +35,12 @@ MachineLegalizer::MachineLegalizer() : TablesInitialized(false) { void MachineLegalizer::computeTables() { for (auto &Op : Actions) { - LLT Ty = Op.first.second; + LLT Ty = Op.first.Type; if (!Ty.isVector()) continue; - auto &Entry = - MaxLegalVectorElts[std::make_pair(Op.first.first, Ty.getElementType())]; + auto &Entry = MaxLegalVectorElts[std::make_pair(Op.first.Opcode, + Ty.getElementType())]; Entry = std::max(Entry, Ty.getNumElements()); } @@ -52,27 +52,30 @@ void MachineLegalizer::computeTables() { // we have any hope of doing well with something like <13 x i3>. Even the common // cases should do better than what we have now. std::pair<MachineLegalizer::LegalizeAction, LLT> -MachineLegalizer::getAction(unsigned Opcode, LLT Ty) const { +MachineLegalizer::getAction(const InstrAspect &Aspect) const { assert(TablesInitialized && "backend forgot to call computeTables"); // These *have* to be implemented for now, they're the fundamental basis of // how everything else is transformed. // FIXME: the long-term plan calls for expansion in terms of load/store (if // they're not legal). - if (Opcode == TargetOpcode::G_SEQUENCE || Opcode == TargetOpcode::G_EXTRACT) - return std::make_pair(Legal, Ty); + if (Aspect.Opcode == TargetOpcode::G_SEQUENCE || + Aspect.Opcode == TargetOpcode::G_EXTRACT) + return std::make_pair(Legal, Aspect.Type); - auto ActionIt = Actions.find(std::make_pair(Opcode, Ty)); + auto ActionIt = Actions.find(Aspect); if (ActionIt != Actions.end()) - return findLegalAction(Opcode, Ty, ActionIt->second); + return findLegalAction(Aspect, ActionIt->second); + unsigned Opcode = Aspect.Opcode; + LLT Ty = Aspect.Type; if (!Ty.isVector()) { - auto DefaultAction = DefaultActions.find(Opcode); + auto DefaultAction = DefaultActions.find(Aspect.Opcode); if (DefaultAction != DefaultActions.end() && DefaultAction->second == Legal) return std::make_pair(Legal, Ty); assert(DefaultAction->second == NarrowScalar && "unexpected default"); - return findLegalAction(Opcode, Ty, NarrowScalar); + return findLegalAction(Aspect, NarrowScalar); } LLT EltTy = Ty.getElementType(); @@ -81,13 +84,13 @@ MachineLegalizer::getAction(unsigned Opcode, LLT Ty) const { auto ScalarAction = ScalarInVectorActions.find(std::make_pair(Opcode, EltTy)); if (ScalarAction != ScalarInVectorActions.end() && ScalarAction->second != Legal) - return findLegalAction(Opcode, EltTy, ScalarAction->second); + return findLegalAction(Aspect, ScalarAction->second); // The element type is legal in principle, but the number of elements is // wrong. auto MaxLegalElts = MaxLegalVectorElts.lookup(std::make_pair(Opcode, EltTy)); if (MaxLegalElts > NumElts) - return findLegalAction(Opcode, Ty, MoreElements); + return findLegalAction(Aspect, MoreElements); if (MaxLegalElts == 0) { // Scalarize if there's no legal vector type, which is just a special case @@ -95,41 +98,46 @@ MachineLegalizer::getAction(unsigned Opcode, LLT Ty) const { return std::make_pair(FewerElements, EltTy); } - return findLegalAction(Opcode, Ty, FewerElements); + return findLegalAction(Aspect, FewerElements); } -std::pair<MachineLegalizer::LegalizeAction, LLT> +std::tuple<MachineLegalizer::LegalizeAction, unsigned, LLT> MachineLegalizer::getAction(const MachineInstr &MI) const { - return getAction(MI.getOpcode(), MI.getType()); + for (unsigned i = 0; i < MI.getNumTypes(); ++i) { + auto Action = getAction({MI.getOpcode(), i, MI.getType(i)}); + if (Action.first != Legal) + return {Action.first, i, Action.second}; + } + return {Legal, 0, LLT{}}; } bool MachineLegalizer::isLegal(const MachineInstr &MI) const { - return getAction(MI).first == Legal; + return std::get<0>(getAction(MI)) == Legal; } -LLT MachineLegalizer::findLegalType(unsigned Opcode, LLT Ty, +LLT MachineLegalizer::findLegalType(const InstrAspect &Aspect, LegalizeAction Action) const { switch(Action) { default: llvm_unreachable("Cannot find legal type"); case Legal: - return Ty; + return Aspect.Type; case NarrowScalar: { - return findLegalType(Opcode, Ty, + return findLegalType(Aspect, [&](LLT Ty) -> LLT { return Ty.halfScalarSize(); }); } case WidenScalar: { - return findLegalType(Opcode, Ty, [&](LLT Ty) -> LLT { + return findLegalType(Aspect, [&](LLT Ty) -> LLT { return Ty.getSizeInBits() < 8 ? LLT::scalar(8) : Ty.doubleScalarSize(); }); } case FewerElements: { - return findLegalType(Opcode, Ty, + return findLegalType(Aspect, [&](LLT Ty) -> LLT { return Ty.halfElements(); }); } case MoreElements: { - return findLegalType( - Opcode, Ty, [&](LLT Ty) -> LLT { return Ty.doubleElements(); }); + return findLegalType(Aspect, + [&](LLT Ty) -> LLT { return Ty.doubleElements(); }); } } } diff --git a/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp b/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp index 2a56ecd6b5b..901bbf1b9b9 100644 --- a/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp +++ b/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp @@ -26,6 +26,7 @@ using namespace llvm; AArch64MachineLegalizer::AArch64MachineLegalizer() { using namespace TargetOpcode; + const LLT p0 = LLT::pointer(0); const LLT s1 = LLT::scalar(1); const LLT s8 = LLT::scalar(8); const LLT s16 = LLT::scalar(16); @@ -37,43 +38,49 @@ AArch64MachineLegalizer::AArch64MachineLegalizer() { for (auto BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) { for (auto Ty : {s32, s64, v2s32, v4s32, v2s64}) - setAction(BinOp, Ty, Legal); + setAction({BinOp, Ty}, Legal); for (auto Ty : {s8, s16}) - setAction(BinOp, Ty, WidenScalar); + setAction({BinOp, Ty}, WidenScalar); } for (auto BinOp : {G_SHL, G_LSHR, G_ASHR, G_SDIV, G_UDIV}) for (auto Ty : {s32, s64}) - setAction(BinOp, Ty, Legal); + setAction({BinOp, Ty}, Legal); for (auto BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV}) for (auto Ty : {s32, s64}) - setAction(BinOp, Ty, Legal); + setAction({BinOp, Ty}, Legal); for (auto MemOp : {G_LOAD, G_STORE}) { for (auto Ty : {s8, s16, s32, s64}) - setAction(MemOp, Ty, Legal); + setAction({MemOp, Ty}, Legal); - setAction(MemOp, s1, WidenScalar); + setAction({MemOp, s1}, WidenScalar); + + // And everything's fine in addrspace 0. + setAction({MemOp, 1, p0}, Legal); } for (auto Ty : {s32, s64}) { - setAction(TargetOpcode::G_CONSTANT, Ty, Legal); - setAction(TargetOpcode::G_FCONSTANT, Ty, Legal); + setAction({TargetOpcode::G_CONSTANT, Ty}, Legal); + setAction({TargetOpcode::G_FCONSTANT, Ty}, Legal); } for (auto Ty : {s1, s8, s16}) - setAction(TargetOpcode::G_CONSTANT, Ty, WidenScalar); + setAction({TargetOpcode::G_CONSTANT, Ty}, WidenScalar); + + setAction({TargetOpcode::G_FCONSTANT, s16}, WidenScalar); - setAction(TargetOpcode::G_FCONSTANT, s16, WidenScalar); + setAction({G_BR, LLT::unsized()}, Legal); - setAction(G_BR, LLT::unsized(), Legal); + setAction({G_FRAME_INDEX, p0}, Legal); - setAction(G_FRAME_INDEX, LLT::pointer(0), Legal); + setAction({G_PTRTOINT, 0, s64}, Legal); + setAction({G_PTRTOINT, 1, p0}, Legal); - setAction(G_PTRTOINT, s64, Legal); - setAction(G_INTTOPTR, LLT::pointer(0), Legal); + setAction({G_INTTOPTR, 0, p0}, Legal); + setAction({G_INTTOPTR, 1, s64}, Legal); computeTables(); } diff --git a/llvm/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp b/llvm/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp index 5f217623cac..946f3b4c0c9 100644 --- a/llvm/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp @@ -52,51 +52,71 @@ namespace { TEST(MachineLegalizerTest, ScalarRISC) { + using namespace TargetOpcode; MachineLegalizer L; // Typical RISCy set of operations based on AArch64. - L.setAction(TargetOpcode::G_ADD, LLT::scalar(8), WidenScalar); - L.setAction(TargetOpcode::G_ADD, LLT::scalar(16), WidenScalar); - L.setAction(TargetOpcode::G_ADD, LLT::scalar(32), Legal); - L.setAction(TargetOpcode::G_ADD, LLT::scalar(64), Legal); + L.setAction({G_ADD, LLT::scalar(8)}, WidenScalar); + L.setAction({G_ADD, LLT::scalar(16)}, WidenScalar); + L.setAction({G_ADD, LLT::scalar(32)}, Legal); + L.setAction({G_ADD, LLT::scalar(64)}, Legal); L.computeTables(); // Check we infer the correct types and actually do what we're told. - ASSERT_EQ(L.getAction(TargetOpcode::G_ADD, LLT::scalar(8)), + ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(8)}), std::make_pair(WidenScalar, LLT::scalar(32))); - ASSERT_EQ(L.getAction(TargetOpcode::G_ADD, LLT::scalar(16)), + ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(16)}), std::make_pair(WidenScalar, LLT::scalar(32))); - ASSERT_EQ(L.getAction(TargetOpcode::G_ADD, LLT::scalar(32)), + ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(32)}), std::make_pair(Legal, LLT::scalar(32))); - ASSERT_EQ(L.getAction(TargetOpcode::G_ADD, LLT::scalar(64)), + ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(64)}), std::make_pair(Legal, LLT::scalar(64))); // Make sure the default for over-sized types applies. - ASSERT_EQ(L.getAction(TargetOpcode::G_ADD, LLT::scalar(128)), + ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(128)}), std::make_pair(NarrowScalar, LLT::scalar(64))); } TEST(MachineLegalizerTest, VectorRISC) { + using namespace TargetOpcode; MachineLegalizer L; // Typical RISCy set of operations based on ARM. - L.setScalarInVectorAction(TargetOpcode::G_ADD, LLT::scalar(8), Legal); - L.setScalarInVectorAction(TargetOpcode::G_ADD, LLT::scalar(16), Legal); - L.setScalarInVectorAction(TargetOpcode::G_ADD, LLT::scalar(32), Legal); - - L.setAction(TargetOpcode::G_ADD, LLT::vector(8, 8), Legal); - L.setAction(TargetOpcode::G_ADD, LLT::vector(16, 8), Legal); - L.setAction(TargetOpcode::G_ADD, LLT::vector(4, 16), Legal); - L.setAction(TargetOpcode::G_ADD, LLT::vector(8, 16), Legal); - L.setAction(TargetOpcode::G_ADD, LLT::vector(2, 32), Legal); - L.setAction(TargetOpcode::G_ADD, LLT::vector(4, 32), Legal); + L.setScalarInVectorAction(G_ADD, LLT::scalar(8), Legal); + L.setScalarInVectorAction(G_ADD, LLT::scalar(16), Legal); + L.setScalarInVectorAction(G_ADD, LLT::scalar(32), Legal); + + L.setAction({G_ADD, LLT::vector(8, 8)}, Legal); + L.setAction({G_ADD, LLT::vector(16, 8)}, Legal); + L.setAction({G_ADD, LLT::vector(4, 16)}, Legal); + L.setAction({G_ADD, LLT::vector(8, 16)}, Legal); + L.setAction({G_ADD, LLT::vector(2, 32)}, Legal); + L.setAction({G_ADD, LLT::vector(4, 32)}, Legal); L.computeTables(); // Check we infer the correct types and actually do what we're told for some // simple cases. - ASSERT_EQ(L.getAction(TargetOpcode::G_ADD, LLT::vector(2, 8)), + ASSERT_EQ(L.getAction({G_ADD, LLT::vector(2, 8)}), std::make_pair(MoreElements, LLT::vector(8, 8))); - ASSERT_EQ(L.getAction(TargetOpcode::G_ADD, LLT::vector(8, 8)), + ASSERT_EQ(L.getAction({G_ADD, LLT::vector(8, 8)}), std::make_pair(Legal, LLT::vector(8, 8))); - ASSERT_EQ(L.getAction(TargetOpcode::G_ADD, LLT::vector(8, 32)), + ASSERT_EQ(L.getAction({G_ADD, LLT::vector(8, 32)}), std::make_pair(FewerElements, LLT::vector(4, 32))); } + +TEST(MachineLegalizerTest, MultipleTypes) { + using namespace TargetOpcode; + MachineLegalizer L; + + // Typical RISCy set of operations based on AArch64. + L.setAction({G_PTRTOINT, 0, LLT::scalar(64)}, Legal); + L.setAction({G_PTRTOINT, 1, LLT::pointer(0)}, Legal); + + L.setAction({G_PTRTOINT, 0, LLT::scalar(32)}, WidenScalar); + L.computeTables(); + + // Check we infer the correct types and actually do what we're told. + ASSERT_EQ(L.getAction({G_PTRTOINT, 0, LLT::scalar(64)}), + std::make_pair(Legal, LLT::scalar(64))); + ASSERT_EQ(L.getAction({G_PTRTOINT, 1, LLT::pointer(0)}), + std::make_pair(Legal, LLT::pointer(0))); +} } |