Index: llvm/trunk/include/llvm/Target/TargetSelectionDAG.td =================================================================== --- llvm/trunk/include/llvm/Target/TargetSelectionDAG.td +++ llvm/trunk/include/llvm/Target/TargetSelectionDAG.td @@ -136,25 +136,25 @@ SDTCisSameAs<0, 1>, SDTCisInt<0> ]>; def SDTIntExtendOp : SDTypeProfile<1, 1, [ // sext, zext, anyext - SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0> + SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1> ]>; def SDTIntTruncOp : SDTypeProfile<1, 1, [ // trunc - SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<0, 1> + SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1> ]>; def SDTFPUnaryOp : SDTypeProfile<1, 1, [ // fneg, fsqrt, etc SDTCisSameAs<0, 1>, SDTCisFP<0> ]>; def SDTFPRoundOp : SDTypeProfile<1, 1, [ // fround - SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1> + SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1> ]>; def SDTFPExtendOp : SDTypeProfile<1, 1, [ // fextend - SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0> + SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1> ]>; def SDTIntToFPOp : SDTypeProfile<1, 1, [ // [su]int_to_fp - SDTCisFP<0>, SDTCisInt<1> + SDTCisFP<0>, SDTCisInt<1>, SDTCisSameNumEltsAs<0, 1> ]>; def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int - SDTCisInt<0>, SDTCisFP<1> + SDTCisInt<0>, SDTCisFP<1>, SDTCisSameNumEltsAs<0, 1> ]>; def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>, @@ -174,7 +174,7 @@ ]>; def SDTVSelect : SDTypeProfile<1, 3, [ // vselect - SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>, SDTCisSameNumEltsAs<0, 1> + SDTCisVec<0>, SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>, SDTCisSameNumEltsAs<0, 1> ]>; def SDTSelectCC : SDTypeProfile<1, 5, [ // select_cc Index: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h =================================================================== --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h @@ -144,9 +144,10 @@ /// be a vector type VT. bool EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VT, TreePattern &TP); - /// EnforceVectorSameNumElts - 'this' is now constrained to - /// be a vector with same num elements as VT. - bool EnforceVectorSameNumElts(EEVT::TypeSet &VT, TreePattern &TP); + /// EnforceSameNumElts - If VTOperand is a scalar, then 'this' is a scalar. + /// If VTOperand is a vector, then 'this' must have the same number of + /// elements. + bool EnforceSameNumElts(EEVT::TypeSet &VT, TreePattern &TP); /// EnforceSameSize - 'this' is now constrained to be the same size as VT. bool EnforceSameSize(EEVT::TypeSet &VT, TreePattern &TP); Index: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp =================================================================== --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp @@ -580,56 +580,74 @@ return MadeChange; } -/// EnforceVectorSameNumElts - 'this' is now constrained to -/// be a vector with same num elements as VTOperand. -bool EEVT::TypeSet::EnforceVectorSameNumElts(EEVT::TypeSet &VTOperand, - TreePattern &TP) { +/// EnforceameNumElts - If VTOperand is a scalar, then 'this' is a scalar. If +/// VTOperand is a vector, then 'this' must have the same number of elements. +bool EEVT::TypeSet::EnforceSameNumElts(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); - // If we know one of the vector types, it forces the other type to agree. + if (isCompletelyUnknown()) + MadeChange = FillWithPossibleTypes(TP); + + if (VTOperand.isCompletelyUnknown()) + MadeChange = VTOperand.FillWithPossibleTypes(TP); + + // If one contains vectors but the other doesn't pull vectors out. + if (!hasVectorTypes()) + MadeChange |= VTOperand.EnforceScalar(TP); + else if (!hasScalarTypes()) + MadeChange |= VTOperand.EnforceVector(TP); + if (!VTOperand.hasVectorTypes()) + MadeChange |= EnforceScalar(TP); + else if (!VTOperand.hasScalarTypes()) + MadeChange |= EnforceVector(TP); + + // If one type is a vector, make sure the other has the same element count. + // If this a scalar, then we are already done with the above. if (isConcrete()) { MVT IVT = getConcrete(); - unsigned NumElems = IVT.getVectorNumElements(); + if (IVT.isVector()) { + unsigned NumElems = IVT.getVectorNumElements(); - // Only keep types that have same elements as 'this'. - TypeSet InputSet(VTOperand); + // Only keep types that have same elements as 'this'. + TypeSet InputSet(VTOperand); - auto I = remove_if(VTOperand.TypeVec, [NumElems](MVT VVT) { - return VVT.getVectorNumElements() != NumElems; - }); - MadeChange |= I != VTOperand.TypeVec.end(); - VTOperand.TypeVec.erase(I, VTOperand.TypeVec.end()); + auto I = remove_if(VTOperand.TypeVec, [NumElems](MVT VVT) { + return VVT.getVectorNumElements() != NumElems; + }); + 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 number elements as '" + - getName() + "'"); - return false; + if (VTOperand.TypeVec.empty()) { // FIXME: Really want an SMLoc here! + TP.error("Type inference contradiction found, forcing '" + + InputSet.getName() + "' to have same number elements as '" + + getName() + "'"); + return false; + } } } else if (VTOperand.isConcrete()) { MVT IVT = VTOperand.getConcrete(); - unsigned NumElems = IVT.getVectorNumElements(); + if (IVT.isVector()) { + unsigned NumElems = IVT.getVectorNumElements(); - // Only keep types that have same elements as VTOperand. - TypeSet InputSet(*this); + // Only keep types that have same elements as VTOperand. + TypeSet InputSet(*this); - auto I = remove_if(TypeVec, [NumElems](MVT VVT) { - return VVT.getVectorNumElements() != NumElems; - }); - MadeChange |= I != TypeVec.end(); - TypeVec.erase(I, TypeVec.end()); + auto I = remove_if(TypeVec, [NumElems](MVT VVT) { + return VVT.getVectorNumElements() != NumElems; + }); + 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 number elements than '" + - VTOperand.getName() + "'"); - return false; + if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! + TP.error("Type inference contradiction found, forcing '" + + InputSet.getName() + "' to have same number elements than '" + + VTOperand.getName() + "'"); + return false; + } } } @@ -1064,7 +1082,7 @@ getOperandNum(x.SDTCisSameNumEltsAs_Info.OtherOperandNum, N, NodeInfo, OResNo); return OtherNode->getExtType(OResNo). - EnforceVectorSameNumElts(NodeToApply->getExtType(ResNo), TP); + EnforceSameNumElts(NodeToApply->getExtType(ResNo), TP); } case SDTCisSameSizeAs: { unsigned OResNo = 0;