Index: include/llvm/CodeGen/GlobalISel/LegalizerInfo.h =================================================================== --- include/llvm/CodeGen/GlobalISel/LegalizerInfo.h +++ include/llvm/CodeGen/GlobalISel/LegalizerInfo.h @@ -205,6 +205,9 @@ std::initializer_list TypesAndMemSizeInit); /// True iff the specified type index is a scalar. LegalityPredicate isScalar(unsigned TypeIdx); +/// True iff the specified type index is a vector. +LegalityPredicate isVector(unsigned TypeIdx); + /// True iff the specified type index is a scalar that's narrower than the given /// size. LegalityPredicate narrowerThan(unsigned TypeIdx, unsigned Size); @@ -235,6 +238,9 @@ /// Add more elements to the type for the given type index to the next power of /// 2. LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min = 0); + +/// Repeat the operation for each vector element. +LegalizeMutation scalarize(unsigned TypeIdx); } // end namespace LegalizeMutations /// A single rule in a legalizer info ruleset. @@ -612,6 +618,13 @@ Mutation); } + LegalizeRuleSet &scalarize(unsigned TypeIdx) { + using namespace LegalityPredicates; + return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)), + LegalizeMutations::scalarize(TypeIdx)); + } + + /// Ensure the scalar is at least as wide as Ty. LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT &Ty) { using namespace LegalityPredicates; Index: lib/CodeGen/GlobalISel/LegalityPredicates.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalityPredicates.cpp +++ lib/CodeGen/GlobalISel/LegalityPredicates.cpp @@ -57,6 +57,12 @@ }; } +LegalityPredicate LegalityPredicates::isVector(unsigned TypeIdx) { + return [=](const LegalityQuery &Query) { + return Query.Types[TypeIdx].isVector(); + }; +} + LegalityPredicate LegalityPredicates::narrowerThan(unsigned TypeIdx, unsigned Size) { return [=](const LegalityQuery &Query) { Index: lib/CodeGen/GlobalISel/LegalizeMutations.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalizeMutations.cpp +++ lib/CodeGen/GlobalISel/LegalizeMutations.cpp @@ -49,3 +49,9 @@ TypeIdx, LLT::vector(NewNumElements, VecTy.getScalarSizeInBits())); }; } + +LegalizeMutation LegalizeMutations::scalarize(unsigned TypeIdx) { + return [=](const LegalityQuery &Query) { + return std::make_pair(TypeIdx, Query.Types[TypeIdx].getElementType()); + }; +} Index: lib/Target/AArch64/AArch64LegalizerInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64LegalizerInfo.cpp +++ lib/Target/AArch64/AArch64LegalizerInfo.cpp @@ -24,6 +24,7 @@ using namespace llvm; using namespace LegalizeActions; +using namespace LegalizeMutations; using namespace LegalityPredicates; AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) { @@ -350,11 +351,6 @@ } return false; }; - auto scalarize = - [](const LegalityQuery &Query, unsigned TypeIdx) { - const LLT &Ty = Query.Types[TypeIdx]; - return std::make_pair(TypeIdx, Ty.getElementType()); - }; // FIXME: This rule is horrible, but specifies the same as what we had // before with the particularly strange definitions removed (e.g. @@ -368,10 +364,10 @@ // Break up vectors with weird elements into scalars .fewerElementsIf( [=](const LegalityQuery &Query) { return notValidElt(Query, 0); }, - [=](const LegalityQuery &Query) { return scalarize(Query, 0); }) + scalarize(0)) .fewerElementsIf( [=](const LegalityQuery &Query) { return notValidElt(Query, 1); }, - [=](const LegalityQuery &Query) { return scalarize(Query, 1); }) + scalarize(1)) // Clamp the big scalar to s8-s512 and make it either a power of 2, 192, // or 384. .clampScalar(BigTyIdx, s8, s512) @@ -412,16 +408,8 @@ return BigTy.getSizeInBits() % LitTy.getSizeInBits() == 0; }) // Any vectors left are the wrong size. Scalarize them. - .fewerElementsIf([](const LegalityQuery &Query) { return true; }, - [](const LegalityQuery &Query) { - return std::make_pair( - 0, Query.Types[0].getElementType()); - }) - .fewerElementsIf([](const LegalityQuery &Query) { return true; }, - [](const LegalityQuery &Query) { - return std::make_pair( - 1, Query.Types[1].getElementType()); - }); + .scalarize(0) + .scalarize(1); } getActionDefinitionsBuilder(G_EXTRACT_VECTOR_ELT) Index: lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp +++ lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp @@ -23,17 +23,13 @@ using namespace llvm; using namespace LegalizeActions; +using namespace LegalizeMutations; +using namespace LegalityPredicates; AMDGPULegalizerInfo::AMDGPULegalizerInfo(const GCNSubtarget &ST, const GCNTargetMachine &TM) { using namespace TargetOpcode; - auto scalarize = - [=](const LegalityQuery &Query, unsigned TypeIdx) { - const LLT &Ty = Query.Types[TypeIdx]; - return std::make_pair(TypeIdx, Ty.getElementType()); - }; - auto GetAddrSpacePtr = [&TM](unsigned AS) { return LLT::pointer(AS, TM.getPointerSizeInBits(AS)); }; @@ -141,13 +137,13 @@ [=](const LegalityQuery &Query) { return Query.Types[0].isVector() && Query.Types[0].getNumElements() % 2 != 0;}, - [=](const LegalityQuery &Query) { return scalarize(Query, 0); }) + scalarize(0)) .fewerElementsIf( [=](const LegalityQuery &Query) { return Query.Types[0].isVector() && Query.Types[0].getElementType().getSizeInBits() < 32; }, - [=](const LegalityQuery &Query) { return scalarize(Query, 0); }) + scalarize(0)) .widenScalarToNextPow2(0); setAction({G_FRAME_INDEX, PrivatePtr}, Legal); @@ -162,14 +158,7 @@ getActionDefinitionsBuilder(G_FPEXT) .legalFor({{S64, S32}, {S32, S16}}) .lowerFor({{S64, S16}}) // FIXME: Implement - .fewerElementsIf( - [](const LegalityQuery &Query) { - return Query.Types[0].isVector(); - }, - [](const LegalityQuery &Query) { - return std::make_pair( - 0, Query.Types[0].getElementType()); - }); + .scalarize(0); // Use actual fsub instruction setAction({G_FSUB, S32}, Legal); @@ -184,25 +173,11 @@ getActionDefinitionsBuilder({G_SEXT, G_ZEXT, G_ANYEXT}) .legalFor({{S64, S32}, {S32, S16}, {S64, S16}, {S32, S1}, {S64, S1}, {S16, S1}}) - .fewerElementsIf( - [](const LegalityQuery &Query) { - return Query.Types[0].isVector(); - }, - [](const LegalityQuery &Query) { - return std::make_pair( - 0, Query.Types[0].getElementType()); - }); + .scalarize(0); getActionDefinitionsBuilder(G_TRUNC) .legalFor({{S32, S64}, {S16, S32}, {S16, S64}}) - .fewerElementsIf( - [](const LegalityQuery &Query) { - return Query.Types[0].isVector(); - }, - [](const LegalityQuery &Query) { - return std::make_pair( - 0, Query.Types[0].getElementType()); - }); + .scalarize(0); setAction({G_FPTOSI, S32}, Legal); setAction({G_FPTOSI, 1, S32}, Legal); @@ -235,8 +210,7 @@ .legalFor({{S1, S32}, {S1, S64}}) .widenScalarToNextPow2(1) .clampScalar(1, S32, S64) - .clampMaxNumElements(0, S1, 1) - .clampMaxNumElements(1, S32, 1); + .scalarize(0); setAction({G_CTLZ, S32}, Legal); setAction({G_CTLZ_ZERO_UNDEF, S32}, Legal); @@ -326,13 +300,13 @@ return Ty.isVector() && (Ty.getScalarSizeInBits() > 32 || Ty.getNumElements() % 2 != 0); }, - [=](const LegalityQuery &Query) { return scalarize(Query, 0); }) + scalarize(0)) // FIXME: Handle 16-bit vectors better .fewerElementsIf( [=](const LegalityQuery &Query) { return Query.Types[0].isVector() && Query.Types[0].getElementType().getSizeInBits() < 32;}, - [=](const LegalityQuery &Query) { return scalarize(Query, 0); }) + scalarize(0)) .clampMaxNumElements(0, S32, 2) .clampMaxNumElements(1, S1, 1); @@ -432,10 +406,10 @@ // Break up vectors with weird elements into scalars .fewerElementsIf( [=](const LegalityQuery &Query) { return notValidElt(Query, 0); }, - [=](const LegalityQuery &Query) { return scalarize(Query, 0); }) + scalarize(0)) .fewerElementsIf( [=](const LegalityQuery &Query) { return notValidElt(Query, 1); }, - [=](const LegalityQuery &Query) { return scalarize(Query, 1); }) + scalarize(1)) .clampScalar(BigTyIdx, S32, S512) .widenScalarIf( [=](const LegalityQuery &Query) { @@ -475,21 +449,8 @@ BigTy.getSizeInBits() <= 512; }) // Any vectors left are the wrong size. Scalarize them. - .fewerElementsIf([](const LegalityQuery &Query) { - return Query.Types[0].isVector(); - }, - [](const LegalityQuery &Query) { - return std::make_pair( - 0, Query.Types[0].getElementType()); - }) - .fewerElementsIf([](const LegalityQuery &Query) { - return Query.Types[1].isVector(); - }, - [](const LegalityQuery &Query) { - return std::make_pair( - 1, Query.Types[1].getElementType()); - }); - + .scalarize(0) + .scalarize(1); } computeTables();