Index: include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h =================================================================== --- include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h +++ include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h @@ -279,8 +279,8 @@ /// instruction, or if unsupported. bool isInstUnsupported(const LegalityQuery &Query) const { auto Action = LI.getAction(Query); - return std::get<0>(Action) == LegalizerInfo::LegalizeAction::Unsupported || - std::get<0>(Action) == LegalizerInfo::LegalizeAction::NotFound; + return std::get<0>(Action) == LegalizeAction::Unsupported || + std::get<0>(Action) == LegalizeAction::NotFound; } }; Index: include/llvm/CodeGen/GlobalISel/LegalizerInfo.h =================================================================== --- include/llvm/CodeGen/GlobalISel/LegalizerInfo.h +++ include/llvm/CodeGen/GlobalISel/LegalizerInfo.h @@ -34,6 +34,53 @@ class MachineIRBuilder; class MachineRegisterInfo; +enum class LegalizeAction : std::uint8_t { + /// The operation is expected to be selectable directly by the target, and + /// no transformation is necessary. + Legal, + + /// The operation should be synthesized from multiple instructions acting on + /// a narrower scalar base-type. For example a 64-bit add might be + /// implemented in terms of 32-bit add-with-carry. + NarrowScalar, + + /// The operation should be implemented in terms of a wider scalar + /// base-type. For example a <2 x s8> add could be implemented as a <2 + /// x s32> add (ignoring the high bits). + WidenScalar, + + /// The (vector) operation should be implemented by splitting it into + /// sub-vectors where the operation is legal. For example a <8 x s64> add + /// might be implemented as 4 separate <2 x s64> adds. + FewerElements, + + /// The (vector) operation should be implemented by widening the input + /// vector and ignoring the lanes added by doing so. For example <2 x i8> is + /// rarely legal, but you might perform an <8 x i8> and then only look at + /// the first two results. + MoreElements, + + /// The operation itself must be expressed in terms of simpler actions on + /// this target. E.g. a SREM replaced by an SDIV and subtraction. + Lower, + + /// The operation should be implemented as a call to some kind of runtime + /// support library. For example this usually happens on machines that don't + /// support floating-point operations natively. + Libcall, + + /// The target wants to do something special with this combination of + /// operand and type. A callback will be issued when it is needed. + Custom, + + /// This operation is completely unsupported on the target. A programming + /// error has occurred. + Unsupported, + + /// Sentinel value for when no action was found in the specified table. + NotFound, +}; + /// 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. @@ -61,53 +108,6 @@ class LegalizerInfo { public: - enum LegalizeAction : std::uint8_t { - /// The operation is expected to be selectable directly by the target, and - /// no transformation is necessary. - Legal, - - /// The operation should be synthesized from multiple instructions acting on - /// a narrower scalar base-type. For example a 64-bit add might be - /// implemented in terms of 32-bit add-with-carry. - NarrowScalar, - - /// The operation should be implemented in terms of a wider scalar - /// base-type. For example a <2 x s8> add could be implemented as a <2 - /// x s32> add (ignoring the high bits). - WidenScalar, - - /// The (vector) operation should be implemented by splitting it into - /// sub-vectors where the operation is legal. For example a <8 x s64> add - /// might be implemented as 4 separate <2 x s64> adds. - FewerElements, - - /// The (vector) operation should be implemented by widening the input - /// vector and ignoring the lanes added by doing so. For example <2 x i8> is - /// rarely legal, but you might perform an <8 x i8> and then only look at - /// the first two results. - MoreElements, - - /// The operation itself must be expressed in terms of simpler actions on - /// this target. E.g. a SREM replaced by an SDIV and subtraction. - Lower, - - /// The operation should be implemented as a call to some kind of runtime - /// support library. For example this usually happens on machines that don't - /// support floating-point operations natively. - Libcall, - - /// The target wants to do something special with this combination of - /// operand and type. A callback will be issued when it is needed. - Custom, - - /// This operation is completely unsupported on the target. A programming - /// error has occurred. - Unsupported, - - /// Sentinel value for when no action was found in the specified table. - NotFound, - }; - LegalizerInfo(); virtual ~LegalizerInfo() = default; @@ -118,11 +118,11 @@ static bool needsLegalizingToDifferentSize(const LegalizeAction Action) { switch (Action) { - case NarrowScalar: - case WidenScalar: - case FewerElements: - case MoreElements: - case Unsupported: + case LegalizeAction::NarrowScalar: + case LegalizeAction::WidenScalar: + case LegalizeAction::FewerElements: + case LegalizeAction::MoreElements: + case LegalizeAction::Unsupported: return true; default: return false; @@ -194,8 +194,8 @@ /// and Unsupported for all other scalar types T. static SizeAndActionsVec unsupportedForDifferentSizes(const SizeAndActionsVec &v) { - return increaseToLargerTypesAndDecreaseToLargest(v, Unsupported, - Unsupported); + return increaseToLargerTypesAndDecreaseToLargest(v, LegalizeAction::Unsupported, + LegalizeAction::Unsupported); } /// A SizeChangeStrategy for the common case where legalization for a @@ -207,20 +207,20 @@ assert(v.size() > 0 && "At least one size that can be legalized towards is needed" " for this SizeChangeStrategy"); - return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar, - NarrowScalar); + return increaseToLargerTypesAndDecreaseToLargest(v, LegalizeAction::WidenScalar, + LegalizeAction::NarrowScalar); } static SizeAndActionsVec widenToLargerTypesUnsupportedOtherwise(const SizeAndActionsVec &v) { - return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar, - Unsupported); + return increaseToLargerTypesAndDecreaseToLargest(v, LegalizeAction::WidenScalar, + LegalizeAction::Unsupported); } static SizeAndActionsVec narrowToSmallerAndUnsupportedIfTooSmall(const SizeAndActionsVec &v) { - return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar, - Unsupported); + return decreaseToSmallerTypesAndIncreaseToSmallest(v, LegalizeAction::NarrowScalar, + LegalizeAction::Unsupported); } static SizeAndActionsVec @@ -228,8 +228,8 @@ assert(v.size() > 0 && "At least one size that can be legalized towards is needed" " for this SizeChangeStrategy"); - return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar, - WidenScalar); + return decreaseToSmallerTypesAndIncreaseToSmallest(v, LegalizeAction::NarrowScalar, + LegalizeAction::WidenScalar); } /// A SizeChangeStrategy for the common case where legalization for a @@ -252,8 +252,8 @@ /// (FewerElements, vector(4,32)). static SizeAndActionsVec moreToWiderTypesAndLessToWidest(const SizeAndActionsVec &v) { - return increaseToLargerTypesAndDecreaseToLargest(v, MoreElements, - FewerElements); + return increaseToLargerTypesAndDecreaseToLargest(v, LegalizeAction::MoreElements, + LegalizeAction::FewerElements); } /// Helper function to implement many typical SizeChangeStrategy functions. @@ -385,16 +385,16 @@ int LargestLegalizableToSameSizeIdx = -1; for(size_t i=0; i(Action)) { - case LegalizerInfo::Legal: + case LegalizeAction::Legal: DEBUG(dbgs() << ".. Already legal\n"); return AlreadyLegal; - case LegalizerInfo::Libcall: + case LegalizeAction::Libcall: DEBUG(dbgs() << ".. Convert to libcall\n"); return libcall(MI); - case LegalizerInfo::NarrowScalar: + case LegalizeAction::NarrowScalar: DEBUG(dbgs() << ".. Narrow scalar\n"); return narrowScalar(MI, std::get<1>(Action), std::get<2>(Action)); - case LegalizerInfo::WidenScalar: + case LegalizeAction::WidenScalar: DEBUG(dbgs() << ".. Widen scalar\n"); return widenScalar(MI, std::get<1>(Action), std::get<2>(Action)); - case LegalizerInfo::Lower: + case LegalizeAction::Lower: DEBUG(dbgs() << ".. Lower\n"); return lower(MI, std::get<1>(Action), std::get<2>(Action)); - case LegalizerInfo::FewerElements: + case LegalizeAction::FewerElements: DEBUG(dbgs() << ".. Reduce number of elements\n"); return fewerElementsVector(MI, std::get<1>(Action), std::get<2>(Action)); - case LegalizerInfo::Custom: + case LegalizeAction::Custom: DEBUG(dbgs() << ".. Custom legalization\n"); return LI.legalizeCustom(MI, MRI, MIRBuilder) ? Legalized : UnableToLegalize; @@ -870,7 +870,7 @@ // Lower (G_FSUB LHS, RHS) to (G_FADD LHS, (G_FNEG RHS)). // First, check if G_FNEG is marked as Lower. If so, we may // end up with an infinite loop as G_FSUB is used to legalize G_FNEG. - if (std::get<0>(LI.getAction({G_FNEG, {Ty}})) == LegalizerInfo::Lower) + if (std::get<0>(LI.getAction({G_FNEG, {Ty}})) == LegalizeAction::Lower) return UnableToLegalize; unsigned Res = MI.getOperand(0).getReg(); unsigned LHS = MI.getOperand(1).getReg(); Index: lib/CodeGen/GlobalISel/LegalizerInfo.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalizerInfo.cpp +++ lib/CodeGen/GlobalISel/LegalizerInfo.cpp @@ -35,14 +35,14 @@ // Set defaults. // FIXME: these two (G_ANYEXT and G_TRUNC?) can be legalized to the // fundamental load/store Jakob proposed. Once loads & stores are supported. - setScalarAction(TargetOpcode::G_ANYEXT, 1, {{1, Legal}}); - setScalarAction(TargetOpcode::G_ZEXT, 1, {{1, Legal}}); - setScalarAction(TargetOpcode::G_SEXT, 1, {{1, Legal}}); - setScalarAction(TargetOpcode::G_TRUNC, 0, {{1, Legal}}); - setScalarAction(TargetOpcode::G_TRUNC, 1, {{1, Legal}}); + setScalarAction(TargetOpcode::G_ANYEXT, 1, {{1, LegalizeAction::Legal}}); + setScalarAction(TargetOpcode::G_ZEXT, 1, {{1, LegalizeAction::Legal}}); + setScalarAction(TargetOpcode::G_SEXT, 1, {{1, LegalizeAction::Legal}}); + setScalarAction(TargetOpcode::G_TRUNC, 0, {{1, LegalizeAction::Legal}}); + setScalarAction(TargetOpcode::G_TRUNC, 1, {{1, LegalizeAction::Legal}}); - setScalarAction(TargetOpcode::G_INTRINSIC, 0, {{1, Legal}}); - setScalarAction(TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS, 0, {{1, Legal}}); + setScalarAction(TargetOpcode::G_INTRINSIC, 0, {{1, LegalizeAction::Legal}}); + setScalarAction(TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS, 0, {{1, LegalizeAction::Legal}}); setLegalizeScalarToDifferentSizeStrategy( TargetOpcode::G_IMPLICIT_DEF, 0, narrowToSmallerAndUnsupportedIfTooSmall); @@ -63,7 +63,7 @@ TargetOpcode::G_EXTRACT, 0, narrowToSmallerAndUnsupportedIfTooSmall); setLegalizeScalarToDifferentSizeStrategy( TargetOpcode::G_EXTRACT, 1, narrowToSmallerAndUnsupportedIfTooSmall); - setScalarAction(TargetOpcode::G_FNEG, 0, {{1, Lower}}); + setScalarAction(TargetOpcode::G_FNEG, 0, {{1, LegalizeAction::Lower}}); } void LegalizerInfo::computeTables() { @@ -127,7 +127,7 @@ std::sort(VectorSpecifiedActions.second.begin(), VectorSpecifiedActions.second.end()); const uint16_t ElementSize = VectorSpecifiedActions.first; - ElementSizesSeen.push_back({ElementSize, Legal}); + ElementSizesSeen.push_back({ElementSize, LegalizeAction::Legal}); checkPartialSizeAndActionsVector(VectorSpecifiedActions.second); // For vector types, we assume that the best way to adapt the number // of elements is to the next larger number of elements type for which @@ -162,7 +162,7 @@ // probably going to need specialized lookup structures for various types before // 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 +std::pair LegalizerInfo::getAspectAction(const InstrAspect &Aspect) const { assert(TablesInitialized && "backend forgot to call computeTables"); // These *have* to be implemented for now, they're the fundamental basis of @@ -186,17 +186,17 @@ return MRI.getType(MI.getOperand(OpIdx).getReg()); } -std::tuple +std::tuple LegalizerInfo::getAction(const LegalityQuery &Query) const { for (unsigned i = 0; i < Query.Types.size(); ++i) { auto Action = getAspectAction({Query.Opcode, i, Query.Types[i]}); - if (Action.first != Legal) + if (Action.first != LegalizeAction::Legal) return std::make_tuple(Action.first, i, Action.second); } - return std::make_tuple(Legal, 0, LLT{}); + return std::make_tuple(LegalizeAction::Legal, 0, LLT{}); } -std::tuple +std::tuple LegalizerInfo::getAction(const MachineInstr &MI, const MachineRegisterInfo &MRI) const { SmallVector Types; @@ -223,7 +223,7 @@ bool LegalizerInfo::isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const { - return std::get<0>(getAction(MI, MRI)) == Legal; + return std::get<0>(getAction(MI, MRI)) == LegalizeAction::Legal; } bool LegalizerInfo::legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, @@ -284,18 +284,18 @@ LegalizeAction Action = Vec[VecIdx].second; switch (Action) { - case Legal: - case Lower: - case Libcall: - case Custom: + case LegalizeAction::Legal: + case LegalizeAction::Lower: + case LegalizeAction::Libcall: + case LegalizeAction::Custom: return {Size, Action}; - case FewerElements: + case LegalizeAction::FewerElements: // FIXME: is this special case still needed and correct? // Special case for scalarization: - if (Vec == SizeAndActionsVec({{1, FewerElements}})) - return {1, FewerElements}; + if (Vec == SizeAndActionsVec({{1, LegalizeAction::FewerElements}})) + return {1, LegalizeAction::FewerElements}; LLVM_FALLTHROUGH; - case NarrowScalar: { + case LegalizeAction::NarrowScalar: { // The following needs to be a loop, as for now, we do allow needing to // go over "Unsupported" bit sizes before finding a legalizable bit size. // e.g. (s8, WidenScalar), (s9, Unsupported), (s32, Legal). if Size==8, @@ -305,37 +305,37 @@ // "Unsupported" unless at the ends of the vector. for (int i = VecIdx - 1; i >= 0; --i) if (!needsLegalizingToDifferentSize(Vec[i].second) && - Vec[i].second != Unsupported) + Vec[i].second != LegalizeAction::Unsupported) return {Vec[i].first, Action}; llvm_unreachable(""); } - case WidenScalar: - case MoreElements: { + case LegalizeAction::WidenScalar: + case LegalizeAction::MoreElements: { // See above, the following needs to be a loop, at least for now. for (std::size_t i = VecIdx + 1; i < Vec.size(); ++i) if (!needsLegalizingToDifferentSize(Vec[i].second) && - Vec[i].second != Unsupported) + Vec[i].second != LegalizeAction::Unsupported) return {Vec[i].first, Action}; llvm_unreachable(""); } - case Unsupported: - return {Size, Unsupported}; - case NotFound: + case LegalizeAction::Unsupported: + return {Size, LegalizeAction::Unsupported}; + case LegalizeAction::NotFound: llvm_unreachable("NotFound"); } llvm_unreachable("Action has an unknown enum value"); } -std::pair +std::pair LegalizerInfo::findScalarLegalAction(const InstrAspect &Aspect) const { assert(Aspect.Type.isScalar() || Aspect.Type.isPointer()); if (Aspect.Opcode < FirstOp || Aspect.Opcode > LastOp) - return {NotFound, LLT()}; + return {LegalizeAction::NotFound, LLT()}; const unsigned OpcodeIdx = Aspect.Opcode - FirstOp; if (Aspect.Type.isPointer() && AddrSpace2PointerActions[OpcodeIdx].find(Aspect.Type.getAddressSpace()) == AddrSpace2PointerActions[OpcodeIdx].end()) { - return {NotFound, LLT()}; + return {LegalizeAction::NotFound, LLT()}; } const SmallVector &Actions = Aspect.Type.isPointer() @@ -344,7 +344,7 @@ ->second : ScalarActions[OpcodeIdx]; if (Aspect.Idx >= Actions.size()) - return {NotFound, LLT()}; + return {LegalizeAction::NotFound, LLT()}; const SizeAndActionsVec &Vec = Actions[Aspect.Idx]; // FIXME: speed up this search, e.g. by using a results cache for repeated // queries? @@ -355,17 +355,17 @@ SizeAndAction.first)}; } -std::pair +std::pair LegalizerInfo::findVectorLegalAction(const InstrAspect &Aspect) const { assert(Aspect.Type.isVector()); // First legalize the vector element size, then legalize the number of // lanes in the vector. if (Aspect.Opcode < FirstOp || Aspect.Opcode > LastOp) - return {NotFound, Aspect.Type}; + return {LegalizeAction::NotFound, Aspect.Type}; const unsigned OpcodeIdx = Aspect.Opcode - FirstOp; const unsigned TypeIdx = Aspect.Idx; if (TypeIdx >= ScalarInVectorActions[OpcodeIdx].size()) - return {NotFound, Aspect.Type}; + return {LegalizeAction::NotFound, Aspect.Type}; const SizeAndActionsVec &ElemSizeVec = ScalarInVectorActions[OpcodeIdx][TypeIdx]; @@ -374,13 +374,13 @@ findAction(ElemSizeVec, Aspect.Type.getScalarSizeInBits()); IntermediateType = LLT::vector(Aspect.Type.getNumElements(), ElementSizeAndAction.first); - if (ElementSizeAndAction.second != Legal) + if (ElementSizeAndAction.second != LegalizeAction::Legal) return {ElementSizeAndAction.second, IntermediateType}; auto i = NumElements2Actions[OpcodeIdx].find( IntermediateType.getScalarSizeInBits()); if (i == NumElements2Actions[OpcodeIdx].end()) { - return {NotFound, IntermediateType}; + return {LegalizeAction::NotFound, IntermediateType}; } const SizeAndActionsVec &NumElementsVec = (*i).second[TypeIdx]; auto NumElementsAndAction = Index: lib/Target/AArch64/AArch64LegalizerInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64LegalizerInfo.cpp +++ lib/Target/AArch64/AArch64LegalizerInfo.cpp @@ -40,7 +40,7 @@ result.push_back(v[i]); if (i + 1 < v[i].first && i + 1 < v.size() && v[i + 1].first != v[i].first + 1) - result.push_back({v[i].first + 1, LegalizerInfo::Unsupported}); + result.push_back({v[i].first + 1, LegalizeAction::Unsupported}); } } @@ -48,14 +48,14 @@ widen_1_narrow_128_ToLargest(const LegalizerInfo::SizeAndActionsVec &v) { assert(v.size() >= 1); assert(v[0].first > 2); - LegalizerInfo::SizeAndActionsVec result = {{1, LegalizerInfo::WidenScalar}, - {2, LegalizerInfo::Unsupported}}; + LegalizerInfo::SizeAndActionsVec result = {{1, LegalizeAction::WidenScalar}, + {2, LegalizeAction::Unsupported}}; addAndInterleaveWithUnsupported(result, v); auto Largest = result.back().first; assert(Largest + 1 < 128); - result.push_back({Largest + 1, LegalizerInfo::Unsupported}); - result.push_back({128, LegalizerInfo::NarrowScalar}); - result.push_back({129, LegalizerInfo::Unsupported}); + result.push_back({Largest + 1, LegalizeAction::Unsupported}); + result.push_back({128, LegalizeAction::NarrowScalar}); + result.push_back({129, LegalizeAction::Unsupported}); return result; } @@ -63,12 +63,12 @@ widen_16(const LegalizerInfo::SizeAndActionsVec &v) { assert(v.size() >= 1); assert(v[0].first > 17); - LegalizerInfo::SizeAndActionsVec result = {{1, LegalizerInfo::Unsupported}, - {16, LegalizerInfo::WidenScalar}, - {17, LegalizerInfo::Unsupported}}; + LegalizerInfo::SizeAndActionsVec result = {{1, LegalizeAction::Unsupported}, + {16, LegalizeAction::WidenScalar}, + {17, LegalizeAction::Unsupported}}; addAndInterleaveWithUnsupported(result, v); auto Largest = result.back().first; - result.push_back({Largest + 1, LegalizerInfo::Unsupported}); + result.push_back({Largest + 1, LegalizeAction::Unsupported}); return result; } @@ -77,11 +77,11 @@ assert(v.size() >= 1); assert(v[0].first > 9); LegalizerInfo::SizeAndActionsVec result = { - {1, LegalizerInfo::WidenScalar}, {2, LegalizerInfo::Unsupported}, - {8, LegalizerInfo::WidenScalar}, {9, LegalizerInfo::Unsupported}}; + {1, LegalizeAction::WidenScalar}, {2, LegalizeAction::Unsupported}, + {8, LegalizeAction::WidenScalar}, {9, LegalizeAction::Unsupported}}; addAndInterleaveWithUnsupported(result, v); auto Largest = result.back().first; - result.push_back({Largest + 1, LegalizerInfo::Unsupported}); + result.push_back({Largest + 1, LegalizeAction::Unsupported}); return result; } @@ -90,12 +90,12 @@ assert(v.size() >= 1); assert(v[0].first > 17); LegalizerInfo::SizeAndActionsVec result = { - {1, LegalizerInfo::WidenScalar}, {2, LegalizerInfo::Unsupported}, - {8, LegalizerInfo::WidenScalar}, {9, LegalizerInfo::Unsupported}, - {16, LegalizerInfo::WidenScalar}, {17, LegalizerInfo::Unsupported}}; + {1, LegalizeAction::WidenScalar}, {2, LegalizeAction::Unsupported}, + {8, LegalizeAction::WidenScalar}, {9, LegalizeAction::Unsupported}, + {16, LegalizeAction::WidenScalar}, {17, LegalizeAction::Unsupported}}; addAndInterleaveWithUnsupported(result, v); auto Largest = result.back().first; - result.push_back({Largest + 1, LegalizerInfo::Unsupported}); + result.push_back({Largest + 1, LegalizeAction::Unsupported}); return result; } @@ -104,12 +104,12 @@ assert(v.size() >= 1); assert(v[0].first > 17); LegalizerInfo::SizeAndActionsVec result = { - {1, LegalizerInfo::WidenScalar}, {2, LegalizerInfo::Unsupported}, - {8, LegalizerInfo::WidenScalar}, {9, LegalizerInfo::Unsupported}, - {16, LegalizerInfo::WidenScalar}, {17, LegalizerInfo::Unsupported}}; + {1, LegalizeAction::WidenScalar}, {2, LegalizeAction::Unsupported}, + {8, LegalizeAction::WidenScalar}, {9, LegalizeAction::Unsupported}, + {16, LegalizeAction::WidenScalar}, {17, LegalizeAction::Unsupported}}; addAndInterleaveWithUnsupported(result, v); auto Largest = result.back().first; - result.push_back({Largest + 1, LegalizerInfo::NarrowScalar}); + result.push_back({Largest + 1, LegalizeAction::NarrowScalar}); return result; } @@ -118,13 +118,13 @@ assert(v.size() >= 1); assert(v[0].first > 33); LegalizerInfo::SizeAndActionsVec result = { - {1, LegalizerInfo::WidenScalar}, {2, LegalizerInfo::Unsupported}, - {8, LegalizerInfo::WidenScalar}, {9, LegalizerInfo::Unsupported}, - {16, LegalizerInfo::WidenScalar}, {17, LegalizerInfo::Unsupported}, - {32, LegalizerInfo::WidenScalar}, {33, LegalizerInfo::Unsupported}}; + {1, LegalizeAction::WidenScalar}, {2, LegalizeAction::Unsupported}, + {8, LegalizeAction::WidenScalar}, {9, LegalizeAction::Unsupported}, + {16, LegalizeAction::WidenScalar}, {17, LegalizeAction::Unsupported}, + {32, LegalizeAction::WidenScalar}, {33, LegalizeAction::Unsupported}}; addAndInterleaveWithUnsupported(result, v); auto Largest = result.back().first; - result.push_back({Largest + 1, LegalizerInfo::Unsupported}); + result.push_back({Largest + 1, LegalizeAction::Unsupported}); return result; } @@ -142,143 +142,143 @@ const LLT v2s64 = LLT::vector(2, 64); for (auto Ty : {p0, s1, s8, s16, s32, s64}) - setAction({G_IMPLICIT_DEF, Ty}, Legal); + setAction({G_IMPLICIT_DEF, Ty}, LegalizeAction::Legal); for (auto Ty : {s16, s32, s64, p0}) - setAction({G_PHI, Ty}, Legal); + setAction({G_PHI, Ty}, LegalizeAction::Legal); setLegalizeScalarToDifferentSizeStrategy(G_PHI, 0, widen_1_8); for (auto Ty : { s32, s64 }) - setAction({G_BSWAP, Ty}, Legal); + setAction({G_BSWAP, Ty}, LegalizeAction::Legal); for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR, G_SHL}) { // These operations naturally get the right answer when used on // GPR32, even if the actual type is narrower. for (auto Ty : {s32, s64, v2s32, v4s32, v2s64}) - setAction({BinOp, Ty}, Legal); + setAction({BinOp, Ty}, LegalizeAction::Legal); if (BinOp != G_ADD) setLegalizeScalarToDifferentSizeStrategy(BinOp, 0, widen_1_8_16_narrowToLargest); } - setAction({G_GEP, p0}, Legal); - setAction({G_GEP, 1, s64}, Legal); + setAction({G_GEP, p0}, LegalizeAction::Legal); + setAction({G_GEP, 1, s64}, LegalizeAction::Legal); setLegalizeScalarToDifferentSizeStrategy(G_GEP, 1, widen_1_8_16_32); - setAction({G_PTR_MASK, p0}, Legal); + setAction({G_PTR_MASK, p0}, LegalizeAction::Legal); for (unsigned BinOp : {G_LSHR, G_ASHR, G_SDIV, G_UDIV}) { for (auto Ty : {s32, s64}) - setAction({BinOp, Ty}, Legal); + setAction({BinOp, Ty}, LegalizeAction::Legal); setLegalizeScalarToDifferentSizeStrategy(BinOp, 0, widen_1_8_16); } for (unsigned BinOp : {G_SREM, G_UREM}) for (auto Ty : { s1, s8, s16, s32, s64 }) - setAction({BinOp, Ty}, Lower); + setAction({BinOp, Ty}, LegalizeAction::Lower); for (unsigned Op : {G_SMULO, G_UMULO}) { - setAction({Op, 0, s64}, Lower); - setAction({Op, 1, s1}, Legal); + setAction({Op, 0, s64}, LegalizeAction::Lower); + setAction({Op, 1, s1}, LegalizeAction::Legal); } for (unsigned Op : {G_UADDE, G_USUBE, G_SADDO, G_SSUBO, G_SMULH, G_UMULH}) { for (auto Ty : { s32, s64 }) - setAction({Op, Ty}, Legal); + setAction({Op, Ty}, LegalizeAction::Legal); - setAction({Op, 1, s1}, Legal); + setAction({Op, 1, s1}, LegalizeAction::Legal); } for (unsigned BinOp : {G_FADD, G_FSUB, G_FMA, G_FMUL, G_FDIV}) for (auto Ty : {s32, s64}) - setAction({BinOp, Ty}, Legal); + setAction({BinOp, Ty}, LegalizeAction::Legal); for (unsigned BinOp : {G_FREM, G_FPOW}) { - setAction({BinOp, s32}, Libcall); - setAction({BinOp, s64}, Libcall); + setAction({BinOp, s32}, LegalizeAction::Libcall); + setAction({BinOp, s64}, LegalizeAction::Libcall); } for (auto Ty : {s32, s64, p0}) { - setAction({G_INSERT, Ty}, Legal); - setAction({G_INSERT, 1, Ty}, Legal); + setAction({G_INSERT, Ty}, LegalizeAction::Legal); + setAction({G_INSERT, 1, Ty}, LegalizeAction::Legal); } setLegalizeScalarToDifferentSizeStrategy(G_INSERT, 0, widen_1_8_16_narrowToLargest); for (auto Ty : {s1, s8, s16}) { - setAction({G_INSERT, 1, Ty}, Legal); + setAction({G_INSERT, 1, Ty}, LegalizeAction::Legal); // FIXME: Can't widen the sources because that violates the constraints on // G_INSERT (It seems entirely reasonable that inputs shouldn't overlap). } for (auto Ty : {s1, s8, s16, s32, s64, p0}) - setAction({G_EXTRACT, Ty}, Legal); + setAction({G_EXTRACT, Ty}, LegalizeAction::Legal); for (auto Ty : {s32, s64}) - setAction({G_EXTRACT, 1, Ty}, Legal); + setAction({G_EXTRACT, 1, Ty}, LegalizeAction::Legal); for (unsigned MemOp : {G_LOAD, G_STORE}) { for (auto Ty : {s8, s16, s32, s64, p0, v2s32}) - setAction({MemOp, Ty}, Legal); + setAction({MemOp, Ty}, LegalizeAction::Legal); setLegalizeScalarToDifferentSizeStrategy(MemOp, 0, widen_1_narrow_128_ToLargest); // And everything's fine in addrspace 0. - setAction({MemOp, 1, p0}, Legal); + setAction({MemOp, 1, p0}, LegalizeAction::Legal); } // Constants for (auto Ty : {s32, s64}) { - setAction({TargetOpcode::G_CONSTANT, Ty}, Legal); - setAction({TargetOpcode::G_FCONSTANT, Ty}, Legal); + setAction({TargetOpcode::G_CONSTANT, Ty}, LegalizeAction::Legal); + setAction({TargetOpcode::G_FCONSTANT, Ty}, LegalizeAction::Legal); } - setAction({G_CONSTANT, p0}, Legal); + setAction({G_CONSTANT, p0}, LegalizeAction::Legal); setLegalizeScalarToDifferentSizeStrategy(G_CONSTANT, 0, widen_1_8_16); setLegalizeScalarToDifferentSizeStrategy(G_FCONSTANT, 0, widen_16); - setAction({G_ICMP, 1, s32}, Legal); - setAction({G_ICMP, 1, s64}, Legal); - setAction({G_ICMP, 1, p0}, Legal); + setAction({G_ICMP, 1, s32}, LegalizeAction::Legal); + setAction({G_ICMP, 1, s64}, LegalizeAction::Legal); + setAction({G_ICMP, 1, p0}, LegalizeAction::Legal); setLegalizeScalarToDifferentSizeStrategy(G_ICMP, 0, widen_1_8_16); setLegalizeScalarToDifferentSizeStrategy(G_FCMP, 0, widen_1_8_16); setLegalizeScalarToDifferentSizeStrategy(G_ICMP, 1, widen_1_8_16); - setAction({G_ICMP, s32}, Legal); - setAction({G_FCMP, s32}, Legal); - setAction({G_FCMP, 1, s32}, Legal); - setAction({G_FCMP, 1, s64}, Legal); + setAction({G_ICMP, s32}, LegalizeAction::Legal); + setAction({G_FCMP, s32}, LegalizeAction::Legal); + setAction({G_FCMP, 1, s32}, LegalizeAction::Legal); + setAction({G_FCMP, 1, s64}, LegalizeAction::Legal); // Extensions for (auto Ty : { s1, s8, s16, s32, s64 }) { - setAction({G_ZEXT, Ty}, Legal); - setAction({G_SEXT, Ty}, Legal); - setAction({G_ANYEXT, Ty}, Legal); + setAction({G_ZEXT, Ty}, LegalizeAction::Legal); + setAction({G_SEXT, Ty}, LegalizeAction::Legal); + setAction({G_ANYEXT, Ty}, LegalizeAction::Legal); } // FP conversions for (auto Ty : { s16, s32 }) { - setAction({G_FPTRUNC, Ty}, Legal); - setAction({G_FPEXT, 1, Ty}, Legal); + setAction({G_FPTRUNC, Ty}, LegalizeAction::Legal); + setAction({G_FPEXT, 1, Ty}, LegalizeAction::Legal); } for (auto Ty : { s32, s64 }) { - setAction({G_FPTRUNC, 1, Ty}, Legal); - setAction({G_FPEXT, Ty}, Legal); + setAction({G_FPTRUNC, 1, Ty}, LegalizeAction::Legal); + setAction({G_FPEXT, Ty}, LegalizeAction::Legal); } // Conversions for (auto Ty : { s32, s64 }) { - setAction({G_FPTOSI, 0, Ty}, Legal); - setAction({G_FPTOUI, 0, Ty}, Legal); - setAction({G_SITOFP, 1, Ty}, Legal); - setAction({G_UITOFP, 1, Ty}, Legal); + setAction({G_FPTOSI, 0, Ty}, LegalizeAction::Legal); + setAction({G_FPTOUI, 0, Ty}, LegalizeAction::Legal); + setAction({G_SITOFP, 1, Ty}, LegalizeAction::Legal); + setAction({G_UITOFP, 1, Ty}, LegalizeAction::Legal); } setLegalizeScalarToDifferentSizeStrategy(G_FPTOSI, 0, widen_1_8_16); setLegalizeScalarToDifferentSizeStrategy(G_FPTOUI, 0, widen_1_8_16); @@ -286,85 +286,85 @@ setLegalizeScalarToDifferentSizeStrategy(G_UITOFP, 1, widen_1_8_16); for (auto Ty : { s32, s64 }) { - setAction({G_FPTOSI, 1, Ty}, Legal); - setAction({G_FPTOUI, 1, Ty}, Legal); - setAction({G_SITOFP, 0, Ty}, Legal); - setAction({G_UITOFP, 0, Ty}, Legal); + setAction({G_FPTOSI, 1, Ty}, LegalizeAction::Legal); + setAction({G_FPTOUI, 1, Ty}, LegalizeAction::Legal); + setAction({G_SITOFP, 0, Ty}, LegalizeAction::Legal); + setAction({G_UITOFP, 0, Ty}, LegalizeAction::Legal); } // Control-flow for (auto Ty : {s1, s8, s16, s32}) - setAction({G_BRCOND, Ty}, Legal); - setAction({G_BRINDIRECT, p0}, Legal); + setAction({G_BRCOND, Ty}, LegalizeAction::Legal); + setAction({G_BRINDIRECT, p0}, LegalizeAction::Legal); // Select setLegalizeScalarToDifferentSizeStrategy(G_SELECT, 0, widen_1_8_16); for (auto Ty : {s32, s64, p0}) - setAction({G_SELECT, Ty}, Legal); + setAction({G_SELECT, Ty}, LegalizeAction::Legal); - setAction({G_SELECT, 1, s1}, Legal); + setAction({G_SELECT, 1, s1}, LegalizeAction::Legal); // Pointer-handling - setAction({G_FRAME_INDEX, p0}, Legal); - setAction({G_GLOBAL_VALUE, p0}, Legal); + setAction({G_FRAME_INDEX, p0}, LegalizeAction::Legal); + setAction({G_GLOBAL_VALUE, p0}, LegalizeAction::Legal); for (auto Ty : {s1, s8, s16, s32, s64}) - setAction({G_PTRTOINT, 0, Ty}, Legal); + setAction({G_PTRTOINT, 0, Ty}, LegalizeAction::Legal); - setAction({G_PTRTOINT, 1, p0}, Legal); + setAction({G_PTRTOINT, 1, p0}, LegalizeAction::Legal); - setAction({G_INTTOPTR, 0, p0}, Legal); - setAction({G_INTTOPTR, 1, s64}, Legal); + setAction({G_INTTOPTR, 0, p0}, LegalizeAction::Legal); + setAction({G_INTTOPTR, 1, s64}, LegalizeAction::Legal); // Casts for 32 and 64-bit width type are just copies. // Same for 128-bit width type, except they are on the FPR bank. for (auto Ty : {s1, s8, s16, s32, s64, s128}) { - setAction({G_BITCAST, 0, Ty}, Legal); - setAction({G_BITCAST, 1, Ty}, Legal); + setAction({G_BITCAST, 0, Ty}, LegalizeAction::Legal); + setAction({G_BITCAST, 1, Ty}, LegalizeAction::Legal); } // For the sake of copying bits around, the type does not really // matter as long as it fits a register. for (int EltSize = 8; EltSize <= 64; EltSize *= 2) { - setAction({G_BITCAST, 0, LLT::vector(128/EltSize, EltSize)}, Legal); - setAction({G_BITCAST, 1, LLT::vector(128/EltSize, EltSize)}, Legal); + setAction({G_BITCAST, 0, LLT::vector(128/EltSize, EltSize)}, LegalizeAction::Legal); + setAction({G_BITCAST, 1, LLT::vector(128/EltSize, EltSize)}, LegalizeAction::Legal); if (EltSize >= 64) continue; - setAction({G_BITCAST, 0, LLT::vector(64/EltSize, EltSize)}, Legal); - setAction({G_BITCAST, 1, LLT::vector(64/EltSize, EltSize)}, Legal); + setAction({G_BITCAST, 0, LLT::vector(64/EltSize, EltSize)}, LegalizeAction::Legal); + setAction({G_BITCAST, 1, LLT::vector(64/EltSize, EltSize)}, LegalizeAction::Legal); if (EltSize >= 32) continue; - setAction({G_BITCAST, 0, LLT::vector(32/EltSize, EltSize)}, Legal); - setAction({G_BITCAST, 1, LLT::vector(32/EltSize, EltSize)}, Legal); + setAction({G_BITCAST, 0, LLT::vector(32/EltSize, EltSize)}, LegalizeAction::Legal); + setAction({G_BITCAST, 1, LLT::vector(32/EltSize, EltSize)}, LegalizeAction::Legal); } - setAction({G_VASTART, p0}, Legal); + setAction({G_VASTART, p0}, LegalizeAction::Legal); // va_list must be a pointer, but most sized types are pretty easy to handle // as the destination. - setAction({G_VAARG, 1, p0}, Legal); + setAction({G_VAARG, 1, p0}, LegalizeAction::Legal); for (auto Ty : {s8, s16, s32, s64, p0}) - setAction({G_VAARG, Ty}, Custom); + setAction({G_VAARG, Ty}, LegalizeAction::Custom); if (ST.hasLSE()) { for (auto Ty : {s8, s16, s32, s64}) { - setAction({G_ATOMIC_CMPXCHG_WITH_SUCCESS, Ty}, Lower); - setAction({G_ATOMIC_CMPXCHG, Ty}, Legal); + setAction({G_ATOMIC_CMPXCHG_WITH_SUCCESS, Ty}, LegalizeAction::Lower); + setAction({G_ATOMIC_CMPXCHG, Ty}, LegalizeAction::Legal); } - setAction({G_ATOMIC_CMPXCHG, 1, p0}, Legal); + setAction({G_ATOMIC_CMPXCHG, 1, p0}, LegalizeAction::Legal); for (unsigned Op : {G_ATOMICRMW_XCHG, G_ATOMICRMW_ADD, G_ATOMICRMW_SUB, G_ATOMICRMW_AND, G_ATOMICRMW_OR, G_ATOMICRMW_XOR, G_ATOMICRMW_MIN, G_ATOMICRMW_MAX, G_ATOMICRMW_UMIN, G_ATOMICRMW_UMAX}) { for (auto Ty : {s8, s16, s32, s64}) { - setAction({Op, Ty}, Legal); + setAction({Op, Ty}, LegalizeAction::Legal); } - setAction({Op, 1, p0}, Legal); + setAction({Op, 1, p0}, LegalizeAction::Legal); } } @@ -372,16 +372,16 @@ for (unsigned Op : {G_MERGE_VALUES, G_UNMERGE_VALUES}) for (int Sz : {8, 16, 32, 64, 128, 192, 256, 384, 512}) { LLT ScalarTy = LLT::scalar(Sz); - setAction({Op, ScalarTy}, Legal); - setAction({Op, 1, ScalarTy}, Legal); + setAction({Op, ScalarTy}, LegalizeAction::Legal); + setAction({Op, 1, ScalarTy}, LegalizeAction::Legal); if (Sz < 32) continue; for (int EltSize = 8; EltSize <= 64; EltSize *= 2) { if (EltSize >= Sz) continue; LLT VecTy = LLT::vector(Sz / EltSize, EltSize); - setAction({Op, VecTy}, Legal); - setAction({Op, 1, VecTy}, Legal); + setAction({Op, VecTy}, LegalizeAction::Legal); + setAction({Op, 1, VecTy}, LegalizeAction::Legal); } }