From 6e1faaf88621c6228a92023eea7fb9970d42f533 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sat, 25 Jan 2014 17:40:33 +0000 Subject: [PATCH] Don't use EnforceSmallerThan for EnforceVectorSubVectorTypeIs. EnforceSmallerThan doesn't handle vectors quite right and should really enforce that vectors have the same number of elements. Add explicit checks for vector element count differing in EnforceVectorSubVectorTypeIs instead. This removes some unnecessary type checks in X86GenDAGISel.inc. llvm-svn: 200091 --- llvm/utils/TableGen/CodeGenDAGPatterns.cpp | 55 +++++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp index fe2ac1d21bc0..358334f06227 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -580,27 +580,78 @@ bool EEVT::TypeSet::EnforceVectorEltTypeIs(EEVT::TypeSet &VTOperand, /// vector type specified by VTOperand. bool EEVT::TypeSet::EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VTOperand, TreePattern &TP) { + if (TP.hasError()) + return false; + // "This" must be a vector and "VTOperand" must be a vector. bool MadeChange = false; MadeChange |= EnforceVector(TP); MadeChange |= VTOperand.EnforceVector(TP); - // "This" must be larger than "VTOperand." - MadeChange |= VTOperand.EnforceSmallerThan(*this, TP); + // If one side is known to be integer or known to be FP but the other side has + // no information, get at least the type integrality info in there. + if (!hasFloatingPointTypes()) + MadeChange |= VTOperand.EnforceInteger(TP); + else if (!hasIntegerTypes()) + MadeChange |= VTOperand.EnforceFloatingPoint(TP); + if (!VTOperand.hasFloatingPointTypes()) + MadeChange |= EnforceInteger(TP); + else if (!VTOperand.hasIntegerTypes()) + MadeChange |= EnforceFloatingPoint(TP); + + assert(!isCompletelyUnknown() && !VTOperand.isCompletelyUnknown() && + "Should have a type list now"); // If we know the vector type, it forces the scalar types to agree. + // Also force one vector to have more elements than the other. if (isConcrete()) { MVT IVT = getConcrete(); + unsigned NumElems = IVT.getVectorNumElements(); IVT = IVT.getVectorElementType(); EEVT::TypeSet EltTypeSet(IVT.SimpleTy, TP); MadeChange |= VTOperand.EnforceVectorEltTypeIs(EltTypeSet, TP); + + // Only keep types that have less elements than VTOperand. + TypeSet InputSet(VTOperand); + + for (unsigned i = 0; i != VTOperand.TypeVec.size(); ++i) { + assert(isVector(VTOperand.TypeVec[i]) && "EnforceVector didn't work"); + if (MVT(VTOperand.TypeVec[i]).getVectorNumElements() >= NumElems) { + VTOperand.TypeVec.erase(VTOperand.TypeVec.begin()+i--); + MadeChange = true; + } + } + if (VTOperand.TypeVec.empty()) { // FIXME: Really want an SMLoc here! + TP.error("Type inference contradiction found, forcing '" + + InputSet.getName() + "' to have less vector elements than '" + + getName() + "'"); + return false; + } } else if (VTOperand.isConcrete()) { MVT IVT = VTOperand.getConcrete(); + unsigned NumElems = IVT.getVectorNumElements(); IVT = IVT.getVectorElementType(); EEVT::TypeSet EltTypeSet(IVT.SimpleTy, TP); MadeChange |= EnforceVectorEltTypeIs(EltTypeSet, TP); + + // Only keep types that have more elements than 'this'. + TypeSet InputSet(*this); + + for (unsigned i = 0; i != TypeVec.size(); ++i) { + assert(isVector(TypeVec[i]) && "EnforceVector didn't work"); + if (MVT(TypeVec[i]).getVectorNumElements() <= NumElems) { + TypeVec.erase(TypeVec.begin()+i--); + MadeChange = true; + } + } + if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! + TP.error("Type inference contradiction found, forcing '" + + InputSet.getName() + "' to have more vector elements than '" + + VTOperand.getName() + "'"); + return false; + } } return MadeChange;