Index: lib/CodeGen/GlobalISel/LegalizerInfo.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalizerInfo.cpp +++ lib/CodeGen/GlobalISel/LegalizerInfo.cpp @@ -58,6 +58,66 @@ return OS; } +#ifndef NDEBUG +// Make sure the returned mutation makes sense for the match type. +static bool mutationIsSane(const LegalizeRule &Rule, + const LegalityQuery &Q, + std::pair Mutation) { + const unsigned TypeIdx = Mutation.first; + const LLT OldTy = Q.Types[TypeIdx]; + const LLT NewTy = Mutation.second; + + switch (Rule.getAction()) { + case FewerElements: + case MoreElements: { + if (!OldTy.isVector()) + return false; + + if (NewTy.isVector()) { + if (Rule.getAction() == FewerElements) { + // Make sure the element count really decreased. + if (NewTy.getNumElements() >= OldTy.getNumElements()) + return false; + } else { + // Make sure the element count really increased. + if (NewTy.getNumElements() <= OldTy.getNumElements()) + return false; + } + } + + // Make sure the element type didn't change. + return NewTy.getScalarType() == OldTy.getElementType(); + } + case NarrowScalar: + case WidenScalar: { + if (OldTy.isVector()) { + // Number of elements should not change. + if (!NewTy.isVector() || OldTy.getNumElements() != NewTy.getNumElements()) + return false; + } else { + // Both types must be vectors + if (NewTy.isVector()) + return false; + } + + if (Rule.getAction() == NarrowScalar) { + // Make sure the size really decreased. + if (NewTy.getScalarSizeInBits() >= OldTy.getScalarSizeInBits()) + return false; + } else { + // Make sure the size really increased. + if (NewTy.getScalarSizeInBits() <= OldTy.getScalarSizeInBits()) + return false; + } + + return true; + } + default: + return true; + } +} +#endif + LegalizeActionStep LegalizeRuleSet::apply(const LegalityQuery &Query) const { LLVM_DEBUG(dbgs() << "Applying legalizer ruleset to: "; Query.print(dbgs()); dbgs() << "\n"); @@ -65,12 +125,15 @@ LLVM_DEBUG(dbgs() << ".. fallback to legacy rules (no rules defined)\n"); return {LegalizeAction::UseLegacyRules, 0, LLT{}}; } - for (const auto &Rule : Rules) { + for (const LegalizeRule &Rule : Rules) { if (Rule.match(Query)) { LLVM_DEBUG(dbgs() << ".. match\n"); std::pair Mutation = Rule.determineMutation(Query); LLVM_DEBUG(dbgs() << ".. .. " << (unsigned)Rule.getAction() << ", " << Mutation.first << ", " << Mutation.second << "\n"); + assert(mutationIsSane(Rule, Query, Mutation) && + "legality mutation invalid for match"); + assert((Query.Types[Mutation.first] != Mutation.second || Rule.getAction() == Lower || Rule.getAction() == MoreElements ||