From 9a44b3fa588113201f0615d11b2b0882743551bf Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 26 Nov 2015 07:02:18 +0000 Subject: [SelectionDAG] Add a SDTCisSameSizeAs type constraint that can be used to ensure vector widths match even if the element size and count don't. llvm-svn: 254138 --- llvm/utils/TableGen/CodeGenDAGPatterns.cpp | 66 ++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'llvm/utils/TableGen/CodeGenDAGPatterns.cpp') diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp index 025e4197ad2..38a8653535e 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -635,6 +635,60 @@ bool EEVT::TypeSet::EnforceVectorSameNumElts(EEVT::TypeSet &VTOperand, return MadeChange; } +/// EnforceSameSize - 'this' is now constrained to be same size as VTOperand. +bool EEVT::TypeSet::EnforceSameSize(EEVT::TypeSet &VTOperand, + TreePattern &TP) { + if (TP.hasError()) + return false; + + bool MadeChange = false; + + // If we know one of the types, it forces the other type agree. + if (isConcrete()) { + MVT IVT = getConcrete(); + unsigned Size = IVT.getSizeInBits(); + + // Only keep types that have the same size as 'this'. + TypeSet InputSet(VTOperand); + + auto I = std::remove_if(VTOperand.TypeVec.begin(), VTOperand.TypeVec.end(), + [&](MVT VT) { + return VT.getSizeInBits() != Size; + }); + MadeChange |= I != VTOperand.TypeVec.end(); + VTOperand.TypeVec.erase(I, VTOperand.TypeVec.end()); + + if (VTOperand.TypeVec.empty()) { // FIXME: Really want an SMLoc here! + TP.error("Type inference contradiction found, forcing '" + + InputSet.getName() + "' to have same size as '" + + getName() + "'"); + return false; + } + } else if (VTOperand.isConcrete()) { + MVT IVT = VTOperand.getConcrete(); + unsigned Size = IVT.getSizeInBits(); + + // Only keep types that have the same size as VTOperand. + TypeSet InputSet(*this); + + auto I = std::remove_if(TypeVec.begin(), TypeVec.end(), + [&](MVT VT) { + return VT.getSizeInBits() != Size; + }); + MadeChange |= I != TypeVec.end(); + TypeVec.erase(I, TypeVec.end()); + + if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! + TP.error("Type inference contradiction found, forcing '" + + InputSet.getName() + "' to have same size as '" + + VTOperand.getName() + "'"); + return false; + } + } + + return MadeChange; +} + //===----------------------------------------------------------------------===// // Helpers for working with extended types. @@ -874,6 +928,10 @@ SDTypeConstraint::SDTypeConstraint(Record *R) { ConstraintType = SDTCisSameNumEltsAs; x.SDTCisSameNumEltsAs_Info.OtherOperandNum = R->getValueAsInt("OtherOperandNum"); + } else if (R->isSubClassOf("SDTCisSameSizeAs")) { + ConstraintType = SDTCisSameSizeAs; + x.SDTCisSameSizeAs_Info.OtherOperandNum = + R->getValueAsInt("OtherOperandNum"); } else { PrintFatalError("Unrecognized SDTypeConstraint '" + R->getName() + "'!\n"); } @@ -1003,6 +1061,14 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N, return OtherNode->getExtType(OResNo). EnforceVectorSameNumElts(NodeToApply->getExtType(ResNo), TP); } + case SDTCisSameSizeAs: { + unsigned OResNo = 0; + TreePatternNode *OtherNode = + getOperandNum(x.SDTCisSameSizeAs_Info.OtherOperandNum, + N, NodeInfo, OResNo); + return OtherNode->getExtType(OResNo). + EnforceSameSize(NodeToApply->getExtType(ResNo), TP); + } } llvm_unreachable("Invalid ConstraintType!"); } -- cgit v1.2.3