diff options
Diffstat (limited to 'llvm')
36 files changed, 252 insertions, 138 deletions
diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h index 14b1378e726..de39da61bbe 100644 --- a/llvm/include/llvm/CodeGen/ISDOpcodes.h +++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h @@ -323,6 +323,12 @@ namespace ISD {      // i1 then the high bits must conform to getBooleanContents.      SELECT, +    // Select with a vector condition (op #0) and two vector operands (ops #1 +    // and #2), returning a vector result.  All vectors have the same length. +    // Much like the scalar select and setcc, each bit in the condition selects +    // whether the corresponding result element is taken from op #1 or op #2. +    VSELECT, +      // Select with condition operator - This selects between a true value and      // a false value (ops #2 and #3) based on the boolean result of comparing      // the lhs and rhs (ops #0 and #1) of a conditional expression with the @@ -333,16 +339,10 @@ namespace ISD {      // true.  If the result value type is not i1 then the high bits conform      // to getBooleanContents.  The operands to this are the left and right      // operands to compare (ops #0, and #1) and the condition code to compare -    // them with (op #2) as a CondCodeSDNode. +    // them with (op #2) as a CondCodeSDNode. If the operands are vector types +    // then the result type must also be a vector type.      SETCC, -    // RESULT = VSETCC(LHS, RHS, COND) operator - This evaluates to a vector of -    // integer elements with all bits of the result elements set to true if the -    // comparison is true or all cleared if the comparison is false.  The -    // operands to this are the left and right operands to compare (LHS/RHS) and -    // the condition code to compare them with (COND) as a CondCodeSDNode. -    VSETCC, -      // SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded      // integer shift operations, just like ADD/SUB_PARTS.  The operation      // ordering is: diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index c8ccdb23b63..af0e5ccf323 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -560,17 +560,13 @@ public:    ///    SDValue getSetCC(DebugLoc DL, EVT VT, SDValue LHS, SDValue RHS,                     ISD::CondCode Cond) { +    assert(LHS.getValueType().isVector() == RHS.getValueType().isVector() && +      "Cannot compare scalars to vectors"); +    assert(LHS.getValueType().isVector() == VT.isVector() && +      "Cannot compare scalars to vectors");      return getNode(ISD::SETCC, DL, VT, LHS, RHS, getCondCode(Cond));    } -  /// getVSetCC - Helper function to make it easier to build VSetCC's nodes -  /// if you just have an ISD::CondCode instead of an SDValue. -  /// -  SDValue getVSetCC(DebugLoc DL, EVT VT, SDValue LHS, SDValue RHS, -                    ISD::CondCode Cond) { -    return getNode(ISD::VSETCC, DL, VT, LHS, RHS, getCondCode(Cond)); -  } -    /// getSelectCC - Helper function to make it easier to build SelectCC's if you    /// just have an ISD::CondCode instead of an SDValue.    /// diff --git a/llvm/include/llvm/CodeGen/ValueTypes.h b/llvm/include/llvm/CodeGen/ValueTypes.h index 16764838930..f314520ffe1 100644 --- a/llvm/include/llvm/CodeGen/ValueTypes.h +++ b/llvm/include/llvm/CodeGen/ValueTypes.h @@ -438,6 +438,21 @@ namespace llvm {        return MVT::INVALID_SIMPLE_VALUE_TYPE;      } +    /// changeVectorElementTypeToInteger - Return a vector with the same number +    /// of elements as this vector, but with the element type converted to an +    /// integer type with the same bitwidth. +    EVT changeVectorElementTypeToInteger() const { +      if (!isSimple()) +        return changeExtendedVectorElementTypeToInteger(); +      MVT EltTy = getSimpleVT().getVectorElementType(); +      unsigned BitWidth = EltTy.getSizeInBits(); +      MVT IntTy = MVT::getIntegerVT(BitWidth); +      MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements()); +      assert(VecTy != MVT::INVALID_SIMPLE_VALUE_TYPE && +             "Simple vector VT not representable by simple integer vector VT!"); +      return VecTy; +    } +      /// isSimple - Test if the given EVT is simple (as opposed to being      /// extended).      bool isSimple() const { @@ -674,6 +689,7 @@ namespace llvm {      // Methods for handling the Extended-type case in functions above.      // These are all out-of-line to prevent users of this header file      // from having a dependency on Type.h. +    EVT changeExtendedVectorElementTypeToInteger() const;      static EVT getExtendedIntegerVT(LLVMContext &C, unsigned BitWidth);      static EVT getExtendedVectorVT(LLVMContext &C, EVT VT,                                     unsigned NumElements); diff --git a/llvm/include/llvm/Target/TargetLowering.h b/llvm/include/llvm/Target/TargetLowering.h index b5d739a2cb7..2aca5efec78 100644 --- a/llvm/include/llvm/Target/TargetLowering.h +++ b/llvm/include/llvm/Target/TargetLowering.h @@ -113,6 +113,22 @@ public:      ZeroOrNegativeOneBooleanContent // All bits equal to bit 0.    }; +  static ISD::NodeType getExtendForContent(BooleanContent Content) { +    switch (Content) { +    default: +      assert(false && "Unknown BooleanContent!"); +    case UndefinedBooleanContent: +      // Extend by adding rubbish bits. +      return ISD::ANY_EXTEND; +    case ZeroOrOneBooleanContent: +      // Extend by adding zero bits. +      return ISD::ZERO_EXTEND; +    case ZeroOrNegativeOneBooleanContent: +      // Extend by copying the sign bit. +      return ISD::SIGN_EXTEND; +    } +  } +    /// NOTE: The constructor takes ownership of TLOF.    explicit TargetLowering(const TargetMachine &TM,                            const TargetLoweringObjectFile *TLOF); @@ -148,8 +164,7 @@ public:    /// the condition operand of SELECT and BRCOND nodes.  In the case of    /// BRCOND the argument passed is MVT::Other since there are no other    /// operands to get a type hint from. -  virtual -  MVT::SimpleValueType getSetCCResultType(EVT VT) const; +  virtual EVT getSetCCResultType(EVT VT) const;    /// getCmpLibcallReturnType - Return the ValueType for comparison    /// libcalls. Comparions libcalls include floating point comparion calls, @@ -162,7 +177,13 @@ public:    /// "Boolean values" are special true/false values produced by nodes like    /// SETCC and consumed (as the condition) by nodes like SELECT and BRCOND.    /// Not to be confused with general values promoted from i1. -  BooleanContent getBooleanContents() const { return BooleanContents;} +  /// Some cpus distinguish between vectors of boolean and scalars; the isVec +  /// parameter selects between the two kinds.  For example on X86 a scalar +  /// boolean should be zero extended from i1, while the elements of a vector +  /// of booleans should be sign extended from i1. +  BooleanContent getBooleanContents(bool isVec) const { +    return isVec ? BooleanVectorContents : BooleanContents; +  }    /// getSchedulingPreference - Return target scheduling preference.    Sched::Preference getSchedulingPreference() const { @@ -938,6 +959,12 @@ protected:    /// setBooleanContents - Specify how the target extends the result of a    /// boolean value from i1 to a wider type.  See getBooleanContents.    void setBooleanContents(BooleanContent Ty) { BooleanContents = Ty; } +  /// setBooleanVectorContents - Specify how the target extends the result +  /// of a vector boolean value from a vector of i1 to a wider type.  See +  /// getBooleanContents. +  void setBooleanVectorContents(BooleanContent Ty) { +    BooleanVectorContents = Ty; +  }    /// setSchedulingPreference - Specify the target scheduling preference.    void setSchedulingPreference(Sched::Preference Pref) { @@ -1657,6 +1684,10 @@ private:    /// BooleanContents - Information about the contents of the high-bits in    /// boolean values held in a type wider than i1.  See getBooleanContents.    BooleanContent BooleanContents; +  /// BooleanVectorContents - Information about the contents of the high-bits +  /// in boolean vector values when the element type is wider than i1.  See +  /// getBooleanContents. +  BooleanContent BooleanVectorContents;    /// SchedPreferenceInfo - The target scheduling preference: shortest possible    /// total cycles or lowest register usage. diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 1d17473b466..6258cb19c3b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3757,7 +3757,7 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {    if (VT.isInteger() &&        (VT0 == MVT::i1 ||         (VT0.isInteger() && -        TLI.getBooleanContents() == TargetLowering::ZeroOrOneBooleanContent)) && +        TLI.getBooleanContents(false) == TargetLowering::ZeroOrOneBooleanContent)) &&        N1C && N2C && N1C->isNullValue() && N2C->getAPIntValue() == 1) {      SDValue XORNode;      if (VT == VT0) @@ -4112,7 +4112,7 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {          // we know that the element size of the sext'd result matches the          // element size of the compare operands.        if (VT.getSizeInBits() == N0VT.getSizeInBits()) -        return DAG.getVSetCC(N->getDebugLoc(), VT, N0.getOperand(0), +        return DAG.getSetCC(N->getDebugLoc(), VT, N0.getOperand(0),                               N0.getOperand(1),                               cast<CondCodeSDNode>(N0.getOperand(2))->get());        // If the desired elements are smaller or larger than the source @@ -4126,7 +4126,7 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {            EVT::getVectorVT(*DAG.getContext(), MatchingElementType,                             N0VT.getVectorNumElements());          SDValue VsetCC = -          DAG.getVSetCC(N->getDebugLoc(), MatchingVectorType, N0.getOperand(0), +          DAG.getSetCC(N->getDebugLoc(), MatchingVectorType, N0.getOperand(0),                          N0.getOperand(1),                          cast<CondCodeSDNode>(N0.getOperand(2))->get());          return DAG.getSExtOrTrunc(VsetCC, N->getDebugLoc(), VT); @@ -4342,7 +4342,7 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {          // we know that the element size of the sext'd result matches the          // element size of the compare operands.          return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, -                           DAG.getVSetCC(N->getDebugLoc(), VT, N0.getOperand(0), +                           DAG.getSetCC(N->getDebugLoc(), VT, N0.getOperand(0),                                           N0.getOperand(1),                                   cast<CondCodeSDNode>(N0.getOperand(2))->get()),                             DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT, @@ -4358,7 +4358,7 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {          EVT::getVectorVT(*DAG.getContext(), MatchingElementType,                           N0VT.getVectorNumElements());        SDValue VsetCC = -        DAG.getVSetCC(N->getDebugLoc(), MatchingVectorType, N0.getOperand(0), +        DAG.getSetCC(N->getDebugLoc(), MatchingVectorType, N0.getOperand(0),                        N0.getOperand(1),                        cast<CondCodeSDNode>(N0.getOperand(2))->get());        return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, @@ -4526,7 +4526,7 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {          // we know that the element size of the sext'd result matches the          // element size of the compare operands.        if (VT.getSizeInBits() == N0VT.getSizeInBits()) -        return DAG.getVSetCC(N->getDebugLoc(), VT, N0.getOperand(0), +        return DAG.getSetCC(N->getDebugLoc(), VT, N0.getOperand(0),                               N0.getOperand(1),                               cast<CondCodeSDNode>(N0.getOperand(2))->get());        // If the desired elements are smaller or larger than the source @@ -4540,7 +4540,7 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {            EVT::getVectorVT(*DAG.getContext(), MatchingElementType,                             N0VT.getVectorNumElements());          SDValue VsetCC = -          DAG.getVSetCC(N->getDebugLoc(), MatchingVectorType, N0.getOperand(0), +          DAG.getSetCC(N->getDebugLoc(), MatchingVectorType, N0.getOperand(0),                          N0.getOperand(1),                          cast<CondCodeSDNode>(N0.getOperand(2))->get());          return DAG.getSExtOrTrunc(VsetCC, N->getDebugLoc(), VT); @@ -7547,7 +7547,8 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1,    // fold select C, 16, 0 -> shl C, 4    if (N2C && N3C && N3C->isNullValue() && N2C->getAPIntValue().isPowerOf2() && -      TLI.getBooleanContents() == TargetLowering::ZeroOrOneBooleanContent) { +    TLI.getBooleanContents(N0.getValueType().isVector()) == +      TargetLowering::ZeroOrOneBooleanContent) {      // If the caller doesn't want us to simplify this into a zext of a compare,      // don't do it. diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index 08d6c7237a1..de3a568dd1e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -475,11 +475,13 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SELECT_CC(SDNode *N) {  SDValue DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) {    EVT SVT = TLI.getSetCCResultType(N->getOperand(0).getValueType()); -  assert(isTypeLegal(SVT) && "Illegal SetCC type!"); +    DebugLoc dl = N->getDebugLoc(); +  assert(SVT.isVector() == N->getOperand(0).getValueType().isVector() && +         "Vector compare must return a vector result!");    // Get the SETCC result using the canonical SETCC type. -  SDValue SetCC = DAG.getNode(ISD::SETCC, dl, SVT, N->getOperand(0), +  SDValue SetCC = DAG.getNode(N->getOpcode(), dl, SVT, N->getOperand(0),                                N->getOperand(1), N->getOperand(2));    // Convert to the expected type. @@ -729,6 +731,7 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {    case ISD::MEMBARRIER:   Res = PromoteIntOp_MEMBARRIER(N); break;    case ISD::SCALAR_TO_VECTOR:                            Res = PromoteIntOp_SCALAR_TO_VECTOR(N); break; +  case ISD::VSELECT:    case ISD::SELECT:       Res = PromoteIntOp_SELECT(N, OpNo); break;    case ISD::SELECT_CC:    Res = PromoteIntOp_SELECT_CC(N, OpNo); break;    case ISD::SETCC:        Res = PromoteIntOp_SETCC(N, OpNo); break; @@ -921,14 +924,17 @@ SDValue DAGTypeLegalizer::PromoteIntOp_SCALAR_TO_VECTOR(SDNode *N) {  }  SDValue DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) { -  assert(OpNo == 0 && "Only know how to promote condition"); +  assert(OpNo == 0 && "Only know how to promote the condition!"); +  SDValue Cond = N->getOperand(0); +  EVT OpTy = N->getOperand(1).getValueType();    // Promote all the way up to the canonical SetCC type. -  EVT SVT = TLI.getSetCCResultType(N->getOperand(1).getValueType()); -  SDValue Cond = PromoteTargetBoolean(N->getOperand(0), SVT); +  EVT SVT = TLI.getSetCCResultType(N->getOpcode() == ISD::SELECT ? +                                   OpTy.getScalarType() : OpTy); +  Cond = PromoteTargetBoolean(Cond, SVT); -  return SDValue(DAG.UpdateNodeOperands(N, Cond, -                                N->getOperand(1), N->getOperand(2)), 0); +  return SDValue(DAG.UpdateNodeOperands(N, Cond, N->getOperand(1), +                                        N->getOperand(2)), 0);  }  SDValue DAGTypeLegalizer::PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo) { diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 04f6642c948..7b566c6e1fd 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -1113,24 +1113,8 @@ DAGTypeLegalizer::ExpandChainLibCall(RTLIB::Libcall LC,  /// type i1, the bits of which conform to getBooleanContents.  SDValue DAGTypeLegalizer::PromoteTargetBoolean(SDValue Bool, EVT VT) {    DebugLoc dl = Bool.getDebugLoc(); -  ISD::NodeType ExtendCode; -  switch (TLI.getBooleanContents()) { -  default: -    assert(false && "Unknown BooleanContent!"); -  case TargetLowering::UndefinedBooleanContent: -    // Extend to VT by adding rubbish bits. -    ExtendCode = ISD::ANY_EXTEND; -    break; -  case TargetLowering::ZeroOrOneBooleanContent: -    // Extend to VT by adding zero bits. -    ExtendCode = ISD::ZERO_EXTEND; -    break; -  case TargetLowering::ZeroOrNegativeOneBooleanContent: { -    // Extend to VT by copying the sign bit. -    ExtendCode = ISD::SIGN_EXTEND; -    break; -  } -  } +  ISD::NodeType ExtendCode = +    TargetLowering::getExtendForContent(TLI.getBooleanContents(VT.isVector()));    return DAG.getNode(ExtendCode, dl, VT, Bool);  } diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 6c1226271be..a9523f52861 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -272,6 +272,7 @@ private:    SDValue PromoteIntOp_SELECT(SDNode *N, unsigned OpNo);    SDValue PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo);    SDValue PromoteIntOp_SETCC(SDNode *N, unsigned OpNo); +  SDValue PromoteIntOp_VSETCC(SDNode *N, unsigned OpNo);    SDValue PromoteIntOp_Shift(SDNode *N);    SDValue PromoteIntOp_SIGN_EXTEND(SDNode *N);    SDValue PromoteIntOp_SINT_TO_FP(SDNode *N); @@ -573,6 +574,7 @@ private:    SDValue SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N);    SDValue SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo);    SDValue SplitVecOp_CONCAT_VECTORS(SDNode *N); +  SDValue SplitVecOp_VSETCC(SDNode *N);    SDValue SplitVecOp_FP_ROUND(SDNode *N);    //===--------------------------------------------------------------------===// diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp index b53fe255101..39e00492d5c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp @@ -439,14 +439,26 @@ void DAGTypeLegalizer::SplitRes_MERGE_VALUES(SDNode *N,  void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDValue &Lo,                                         SDValue &Hi) { -  SDValue LL, LH, RL, RH; +  SDValue LL, LH, RL, RH, CL, CH;    DebugLoc dl = N->getDebugLoc();    GetSplitOp(N->getOperand(1), LL, LH);    GetSplitOp(N->getOperand(2), RL, RH);    SDValue Cond = N->getOperand(0); -  Lo = DAG.getNode(ISD::SELECT, dl, LL.getValueType(), Cond, LL, RL); -  Hi = DAG.getNode(ISD::SELECT, dl, LH.getValueType(), Cond, LH, RH); +  CL = CH = Cond; +  if (Cond.getValueType().isVector()) { +    assert(Cond.getValueType().getVectorElementType() == MVT::i1 && +           "Condition legalized before result?"); +    unsigned NumElements = Cond.getValueType().getVectorNumElements(); +    EVT VCondTy = EVT::getVectorVT(*DAG.getContext(), MVT::i1, NumElements / 2); +    CL = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VCondTy, Cond, +                     DAG.getIntPtrConstant(0)); +    CH = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VCondTy, Cond, +                     DAG.getIntPtrConstant(NumElements / 2)); +  } + +  Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), CL, LL, RL); +  Hi = DAG.getNode(N->getOpcode(), dl, LH.getValueType(), CH, LH, RH);  }  void DAGTypeLegalizer::SplitRes_SELECT_CC(SDNode *N, SDValue &Lo, diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp index ffff10ce294..6af8e5b7a90 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @@ -158,7 +158,7 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) {    case ISD::CTPOP:    case ISD::SELECT:    case ISD::SELECT_CC: -  case ISD::VSETCC: +  case ISD::SETCC:    case ISD::ZERO_EXTEND:    case ISD::ANY_EXTEND:    case ISD::TRUNCATE: @@ -214,7 +214,7 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) {        Result = ExpandUINT_TO_FLOAT(Op);      else if (Node->getOpcode() == ISD::FNEG)        Result = ExpandFNEG(Op); -    else if (Node->getOpcode() == ISD::VSETCC) +    else if (Node->getOpcode() == ISD::SETCC)        Result = UnrollVSETCC(Op);      else        Result = DAG.UnrollVectorOp(Op.getNode()); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index 4262b86d8bc..f9bcc647559 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -64,8 +64,6 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {    case ISD::SETCC:             R = ScalarizeVecRes_SETCC(N); break;    case ISD::UNDEF:             R = ScalarizeVecRes_UNDEF(N); break;    case ISD::VECTOR_SHUFFLE:    R = ScalarizeVecRes_VECTOR_SHUFFLE(N); break; -  case ISD::VSETCC:            R = ScalarizeVecRes_VSETCC(N); break; -    case ISD::ANY_EXTEND:    case ISD::CTLZ:    case ISD::CTPOP: @@ -244,6 +242,12 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT_CC(SDNode *N) {  }  SDValue DAGTypeLegalizer::ScalarizeVecRes_SETCC(SDNode *N) { +  assert(N->getValueType(0).isVector() == +         N->getOperand(0).getValueType().isVector() && +         "Scalar/Vector type mismatch"); + +  if (N->getValueType(0).isVector()) return ScalarizeVecRes_VSETCC(N); +    SDValue LHS = GetScalarizedVector(N->getOperand(0));    SDValue RHS = GetScalarizedVector(N->getOperand(1));    DebugLoc DL = N->getDebugLoc(); @@ -266,35 +270,23 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N) {  }  SDValue DAGTypeLegalizer::ScalarizeVecRes_VSETCC(SDNode *N) { +  assert(N->getValueType(0).isVector() && +         N->getOperand(0).getValueType().isVector() && +         "Operand types must be vectors"); +    SDValue LHS = GetScalarizedVector(N->getOperand(0));    SDValue RHS = GetScalarizedVector(N->getOperand(1));    EVT NVT = N->getValueType(0).getVectorElementType(); -  EVT SVT = TLI.getSetCCResultType(LHS.getValueType());    DebugLoc DL = N->getDebugLoc();    // Turn it into a scalar SETCC. -  SDValue Res = DAG.getNode(ISD::SETCC, DL, SVT, LHS, RHS, N->getOperand(2)); - -  // VSETCC always returns a sign-extended value, while SETCC may not.  The -  // SETCC result type may not match the vector element type.  Correct these. -  if (NVT.bitsLE(SVT)) { -    // The SETCC result type is bigger than the vector element type. -    // Ensure the SETCC result is sign-extended. -    if (TLI.getBooleanContents() != -        TargetLowering::ZeroOrNegativeOneBooleanContent) -      Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, SVT, Res, -                        DAG.getValueType(MVT::i1)); -    // Truncate to the final type. -    return DAG.getNode(ISD::TRUNCATE, DL, NVT, Res); -  } - -  // The SETCC result type is smaller than the vector element type. -  // If the SetCC result is not sign-extended, chop it down to MVT::i1. -  if (TLI.getBooleanContents() != -        TargetLowering::ZeroOrNegativeOneBooleanContent) -    Res = DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, Res); -  // Sign extend to the final type. -  return DAG.getNode(ISD::SIGN_EXTEND, DL, NVT, Res); +  SDValue Res = DAG.getNode(ISD::SETCC, DL, MVT::i1, LHS, RHS, +                            N->getOperand(2)); +  // Vectors may have a different boolean contents to scalars.  Promote the +  // value appropriately. +  ISD::NodeType ExtendCode = +    TargetLowering::getExtendForContent(TLI.getBooleanContents(true)); +  return DAG.getNode(ExtendCode, DL, NVT, Res);  } @@ -423,6 +415,7 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {      llvm_unreachable("Do not know how to split the result of this operator!");    case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break; +  case ISD::VSELECT:    case ISD::SELECT:       SplitRes_SELECT(N, Lo, Hi); break;    case ISD::SELECT_CC:    SplitRes_SELECT_CC(N, Lo, Hi); break;    case ISD::UNDEF:        SplitRes_UNDEF(N, Lo, Hi); break; @@ -439,7 +432,6 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {      SplitVecRes_LOAD(cast<LoadSDNode>(N), Lo, Hi);      break;    case ISD::SETCC: -  case ISD::VSETCC:      SplitVecRes_SETCC(N, Lo, Hi);      break;    case ISD::VECTOR_SHUFFLE: @@ -746,6 +738,10 @@ void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo,  }  void DAGTypeLegalizer::SplitVecRes_SETCC(SDNode *N, SDValue &Lo, SDValue &Hi) { +  assert(N->getValueType(0).isVector() && +         N->getOperand(0).getValueType().isVector() && +         "Operand types must be vectors"); +    EVT LoVT, HiVT;    DebugLoc DL = N->getDebugLoc();    GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); @@ -971,7 +967,7 @@ bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) {        dbgs() << "\n";  #endif        llvm_unreachable("Do not know how to split this operator's operand!"); - +    case ISD::SETCC:             Res = SplitVecOp_VSETCC(N); break;      case ISD::BITCAST:           Res = SplitVecOp_BITCAST(N); break;      case ISD::EXTRACT_SUBVECTOR: Res = SplitVecOp_EXTRACT_SUBVECTOR(N); break;      case ISD::EXTRACT_VECTOR_ELT:Res = SplitVecOp_EXTRACT_VECTOR_ELT(N); break; @@ -1169,6 +1165,26 @@ SDValue DAGTypeLegalizer::SplitVecOp_CONCAT_VECTORS(SDNode *N) {                       &Elts[0], Elts.size());  } +SDValue DAGTypeLegalizer::SplitVecOp_VSETCC(SDNode *N) { +  assert(N->getValueType(0).isVector() && +         N->getOperand(0).getValueType().isVector() && +         "Operand types must be vectors"); +  // The result has a legal vector type, but the input needs splitting. +  SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes; +  DebugLoc DL = N->getDebugLoc(); +  GetSplitVector(N->getOperand(0), Lo0, Hi0); +  GetSplitVector(N->getOperand(1), Lo1, Hi1); +  unsigned PartElements = Lo0.getValueType().getVectorNumElements(); +  EVT PartResVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1, PartElements); +  EVT WideResVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1, 2*PartElements); + +  LoRes = DAG.getNode(ISD::SETCC, DL, PartResVT, Lo0, Lo1, N->getOperand(2)); +  HiRes = DAG.getNode(ISD::SETCC, DL, PartResVT, Hi0, Hi1, N->getOperand(2)); +  SDValue Con = DAG.getNode(ISD::CONCAT_VECTORS, DL, WideResVT, LoRes, HiRes); +  return PromoteTargetBoolean(Con, N->getValueType(0)); +} + +  SDValue DAGTypeLegalizer::SplitVecOp_FP_ROUND(SDNode *N) {    // The result has a legal vector type, but the input needs splitting.    EVT ResVT = N->getValueType(0); @@ -1229,10 +1245,6 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {    case ISD::VECTOR_SHUFFLE:      Res = WidenVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(N));      break; -  case ISD::VSETCC: -    Res = WidenVecRes_VSETCC(N); -    break; -    case ISD::ADD:    case ISD::AND:    case ISD::BSWAP: @@ -1929,6 +1941,11 @@ SDValue DAGTypeLegalizer::WidenVecRes_SELECT_CC(SDNode *N) {  }  SDValue DAGTypeLegalizer::WidenVecRes_SETCC(SDNode *N) { +  assert(N->getValueType(0).isVector() == +         N->getOperand(0).getValueType().isVector() && +         "Scalar/Vector type mismatch"); +  if (N->getValueType(0).isVector()) return WidenVecRes_VSETCC(N); +    EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));    SDValue InOp1 = GetWidenedVector(N->getOperand(0));    SDValue InOp2 = GetWidenedVector(N->getOperand(1)); @@ -1967,6 +1984,9 @@ SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N) {  }  SDValue DAGTypeLegalizer::WidenVecRes_VSETCC(SDNode *N) { +  assert(N->getValueType(0).isVector() && +         N->getOperand(0).getValueType().isVector() && +         "Operands must be vectors");    EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));    unsigned WidenNumElts = WidenVT.getVectorNumElements(); @@ -1984,7 +2004,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_VSETCC(SDNode *N) {           InOp2.getValueType() == WidenInVT &&           "Input not widened to expected type!");    (void)WidenInVT; -  return DAG.getNode(ISD::VSETCC, N->getDebugLoc(), +  return DAG.getNode(ISD::SETCC, N->getDebugLoc(),                       WidenVT, InOp1, InOp2, N->getOperand(2));  } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index ec7bfbe495c..5f5a880edfa 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -927,13 +927,25 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, EVT VT, bool isT) {    assert(VT.isInteger() && "Cannot create FP integer constant!");    EVT EltVT = VT.getScalarType(); -  assert(Val.getBitWidth() == EltVT.getSizeInBits() && -         "APInt size does not match type size!"); +  const ConstantInt *Elt = &Val; + +  // In some cases the vector type is legal but the element type is illegal and +  // needs to be promoted, for example v8i8 on ARM.  In this case, promote the +  // inserted value (the type does not need to match the vector element type). +  // Any extra bits introduced will be truncated away. +  if (VT.isVector() && TLI.getTypeAction(*getContext(), EltVT) == +      TargetLowering::TypePromoteInteger) { +   EltVT = TLI.getTypeToTransformTo(*getContext(), EltVT); +   APInt NewVal = Elt->getValue().zext(EltVT.getSizeInBits()); +   Elt = ConstantInt::get(*getContext(), NewVal); +  } +  assert(Elt->getBitWidth() == EltVT.getSizeInBits() && +         "APInt size does not match type size!");    unsigned Opc = isT ? ISD::TargetConstant : ISD::Constant;    FoldingSetNodeID ID;    AddNodeIDNode(ID, Opc, getVTList(EltVT), 0, 0); -  ID.AddPointer(&Val); +  ID.AddPointer(Elt);    void *IP = 0;    SDNode *N = NULL;    if ((N = CSEMap.FindNodeOrInsertPos(ID, IP))) @@ -941,7 +953,7 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, EVT VT, bool isT) {        return SDValue(N, 0);    if (!N) { -    N = new (NodeAllocator) ConstantSDNode(isT, &Val, EltVT); +    N = new (NodeAllocator) ConstantSDNode(isT, Elt, EltVT);      CSEMap.InsertNode(N, IP);      AllNodes.push_back(N);    } @@ -1720,8 +1732,8 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, const APInt &Mask,      // The boolean result conforms to getBooleanContents.  Fall through.    case ISD::SETCC:      // If we know the result of a setcc has the top bits zero, use this info. -    if (TLI.getBooleanContents() == TargetLowering::ZeroOrOneBooleanContent && -        BitWidth > 1) +    if (TLI.getBooleanContents(Op.getValueType().isVector()) == +        TargetLowering::ZeroOrOneBooleanContent && BitWidth > 1)        KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - 1);      return;    case ISD::SHL: @@ -2155,7 +2167,7 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{      // The boolean result conforms to getBooleanContents.  Fall through.    case ISD::SETCC:      // If setcc returns 0/-1, all bits are sign bits. -    if (TLI.getBooleanContents() == +    if (TLI.getBooleanContents(Op.getValueType().isVector()) ==          TargetLowering::ZeroOrNegativeOneBooleanContent)        return VTBits;      break; @@ -5965,8 +5977,8 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {    case ISD::FPOWI:  return "fpowi";    case ISD::SETCC:       return "setcc"; -  case ISD::VSETCC:      return "vsetcc";    case ISD::SELECT:      return "select"; +  case ISD::VSELECT:     return "vselect";    case ISD::SELECT_CC:   return "select_cc";    case ISD::INSERT_VECTOR_ELT:   return "insert_vector_elt";    case ISD::EXTRACT_VECTOR_ELT:  return "extract_vector_elt"; diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index d8fa0c93dbd..1337754ee61 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2626,10 +2626,12 @@ void SelectionDAGBuilder::visitSelect(const User &I) {    SDValue Cond     = getValue(I.getOperand(0));    SDValue TrueVal  = getValue(I.getOperand(1));    SDValue FalseVal = getValue(I.getOperand(2)); +  ISD::NodeType OpCode = Cond.getValueType().isVector() ? +    ISD::VSELECT : ISD::SELECT;    for (unsigned i = 0; i != NumValues; ++i) -    Values[i] = DAG.getNode(ISD::SELECT, getCurDebugLoc(), -                          TrueVal.getNode()->getValueType(TrueVal.getResNo()+i), +    Values[i] = DAG.getNode(OpCode, getCurDebugLoc(), +                            TrueVal.getNode()->getValueType(TrueVal.getResNo()+i),                              Cond,                              SDValue(TrueVal.getNode(),                                      TrueVal.getResNo() + i), diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 819e64084f2..c6eeebe606e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -609,6 +609,7 @@ TargetLowering::TargetLowering(const TargetMachine &tm,    ExceptionPointerRegister = 0;    ExceptionSelectorRegister = 0;    BooleanContents = UndefinedBooleanContent; +  BooleanVectorContents = UndefinedBooleanContent;    SchedPreferenceInfo = Sched::Latency;    JumpBufSize = 0;    JumpBufAlignment = 0; @@ -915,7 +916,8 @@ const char *TargetLowering::getTargetNodeName(unsigned Opcode) const {  } -MVT::SimpleValueType TargetLowering::getSetCCResultType(EVT VT) const { +EVT TargetLowering::getSetCCResultType(EVT VT) const { +  assert(!VT.isVector() && "No default SetCC type for vectors!");    return PointerTy.SimpleTy;  } @@ -2191,7 +2193,7 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,          }        } else if (N1C->getAPIntValue() == 1 &&                   (VT == MVT::i1 || -                  getBooleanContents() == ZeroOrOneBooleanContent)) { +                  getBooleanContents(false) == ZeroOrOneBooleanContent)) {          SDValue Op0 = N0;          if (Op0.getOpcode() == ISD::TRUNCATE)            Op0 = Op0.getOperand(0); diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 64ceac4b6e2..62418791cda 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -106,7 +106,7 @@ void ARMTargetLowering::addTypeForNEON(EVT VT, EVT PromotedLdStVT,    EVT ElemTy = VT.getVectorElementType();    if (ElemTy != MVT::i64 && ElemTy != MVT::f64) -    setOperationAction(ISD::VSETCC, VT.getSimpleVT(), Custom); +    setOperationAction(ISD::SETCC, VT.getSimpleVT(), Custom);    setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT.getSimpleVT(), Custom);    if (ElemTy != MVT::i32) {      setOperationAction(ISD::SINT_TO_FP, VT.getSimpleVT(), Expand); @@ -178,6 +178,8 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)    RegInfo = TM.getRegisterInfo();    Itins = TM.getInstrItineraryData(); +  setBooleanVectorContents(ZeroOrNegativeOneBooleanContent); +    if (Subtarget->isTargetDarwin()) {      // Uses VFP for Thumb libfuncs if available.      if (Subtarget->isThumb() && Subtarget->hasVFP2()) { @@ -453,7 +455,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)      setOperationAction(ISD::FDIV, MVT::v2f64, Expand);      setOperationAction(ISD::FREM, MVT::v2f64, Expand);      setOperationAction(ISD::FCOPYSIGN, MVT::v2f64, Expand); -    setOperationAction(ISD::VSETCC, MVT::v2f64, Expand); +    setOperationAction(ISD::SETCC, MVT::v2f64, Expand);      setOperationAction(ISD::FNEG, MVT::v2f64, Expand);      setOperationAction(ISD::FABS, MVT::v2f64, Expand);      setOperationAction(ISD::FSQRT, MVT::v2f64, Expand); @@ -485,8 +487,8 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)      setOperationAction(ISD::SDIV, MVT::v8i8, Custom);      setOperationAction(ISD::UDIV, MVT::v4i16, Custom);      setOperationAction(ISD::UDIV, MVT::v8i8, Custom); -    setOperationAction(ISD::VSETCC, MVT::v1i64, Expand); -    setOperationAction(ISD::VSETCC, MVT::v2i64, Expand); +    setOperationAction(ISD::SETCC, MVT::v1i64, Expand); +    setOperationAction(ISD::SETCC, MVT::v2i64, Expand);      // Neon does not have single instruction SINT_TO_FP and UINT_TO_FP with      // a destination type that is wider than the source.      setOperationAction(ISD::SINT_TO_FP, MVT::v4i16, Custom); @@ -930,6 +932,11 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {    }  } +EVT ARMTargetLowering::getSetCCResultType(EVT VT) const { +  if (!VT.isVector()) return getPointerTy(); +  return VT.changeVectorElementTypeToInteger(); +} +  /// getRegClassFor - Return the register class that should be used for the  /// specified value type.  TargetRegisterClass *ARMTargetLowering::getRegClassFor(EVT VT) const { @@ -4925,7 +4932,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {    case ISD::SRL_PARTS:    case ISD::SRA_PARTS:     return LowerShiftRightParts(Op, DAG);    case ISD::CTTZ:          return LowerCTTZ(Op.getNode(), DAG, Subtarget); -  case ISD::VSETCC:        return LowerVSETCC(Op, DAG); +  case ISD::SETCC:         return LowerVSETCC(Op, DAG);    case ISD::BUILD_VECTOR:  return LowerBUILD_VECTOR(Op, DAG, Subtarget);    case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG);    case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG); diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h index 5bf85d482bd..b06e6594afe 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.h +++ b/llvm/lib/Target/ARM/ARMISelLowering.h @@ -255,6 +255,9 @@ namespace llvm {      virtual const char *getTargetNodeName(unsigned Opcode) const; +    /// getSetCCResultType - Return the value type to use for ISD::SETCC. +    virtual EVT getSetCCResultType(EVT VT) const; +      virtual MachineBasicBlock *        EmitInstrWithCustomInserter(MachineInstr *MI,                                    MachineBasicBlock *MBB) const; diff --git a/llvm/lib/Target/Alpha/AlphaISelLowering.cpp b/llvm/lib/Target/Alpha/AlphaISelLowering.cpp index 68ae71530ac..3057eb8c57f 100644 --- a/llvm/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/llvm/lib/Target/Alpha/AlphaISelLowering.cpp @@ -49,6 +49,7 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM)    // Set up the TargetLowering object.    //I am having problems with shr n i8 1    setBooleanContents(ZeroOrOneBooleanContent); +  setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?    addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass);    addRegisterClass(MVT::f64, Alpha::F8RCRegisterClass); @@ -168,7 +169,7 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM)    computeRegisterProperties();  } -MVT::SimpleValueType AlphaTargetLowering::getSetCCResultType(EVT VT) const { +EVT AlphaTargetLowering::getSetCCResultType(EVT VT) const {    return MVT::i64;  } diff --git a/llvm/lib/Target/Alpha/AlphaISelLowering.h b/llvm/lib/Target/Alpha/AlphaISelLowering.h index 13383f4430f..80f8efaea5d 100644 --- a/llvm/lib/Target/Alpha/AlphaISelLowering.h +++ b/llvm/lib/Target/Alpha/AlphaISelLowering.h @@ -66,7 +66,7 @@ namespace llvm {      virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i64; }      /// getSetCCResultType - Get the SETCC result ValueType -    virtual MVT::SimpleValueType getSetCCResultType(EVT VT) const; +    virtual EVT getSetCCResultType(EVT VT) const;      /// LowerOperation - Provide custom lowering hooks for some operations.      /// diff --git a/llvm/lib/Target/Blackfin/BlackfinISelLowering.cpp b/llvm/lib/Target/Blackfin/BlackfinISelLowering.cpp index 43aad433401..7d4c45fdf66 100644 --- a/llvm/lib/Target/Blackfin/BlackfinISelLowering.cpp +++ b/llvm/lib/Target/Blackfin/BlackfinISelLowering.cpp @@ -42,6 +42,7 @@ using namespace llvm;  BlackfinTargetLowering::BlackfinTargetLowering(TargetMachine &TM)    : TargetLowering(TM, new TargetLoweringObjectFileELF()) {    setBooleanContents(ZeroOrOneBooleanContent); +  setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?    setStackPointerRegisterToSaveRestore(BF::SP);    setIntDivIsCheap(false); @@ -135,7 +136,7 @@ const char *BlackfinTargetLowering::getTargetNodeName(unsigned Opcode) const {    }  } -MVT::SimpleValueType BlackfinTargetLowering::getSetCCResultType(EVT VT) const { +EVT BlackfinTargetLowering::getSetCCResultType(EVT VT) const {    // SETCC always sets the CC register. Technically that is an i1 register, but    // that type is not legal, so we treat it as an i32 register.    return MVT::i32; diff --git a/llvm/lib/Target/Blackfin/BlackfinISelLowering.h b/llvm/lib/Target/Blackfin/BlackfinISelLowering.h index b65775b9285..90908baaae9 100644 --- a/llvm/lib/Target/Blackfin/BlackfinISelLowering.h +++ b/llvm/lib/Target/Blackfin/BlackfinISelLowering.h @@ -33,7 +33,7 @@ namespace llvm {    public:      BlackfinTargetLowering(TargetMachine &TM);      virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i16; } -    virtual MVT::SimpleValueType getSetCCResultType(EVT VT) const; +    virtual EVT getSetCCResultType(EVT VT) const;      virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;      virtual void ReplaceNodeResults(SDNode *N,                                      SmallVectorImpl<SDValue> &Results, diff --git a/llvm/lib/Target/CellSPU/SPUISelLowering.cpp b/llvm/lib/Target/CellSPU/SPUISelLowering.cpp index 1a081e9e6d7..cfd29cf90dd 100644 --- a/llvm/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/llvm/lib/Target/CellSPU/SPUISelLowering.cpp @@ -439,6 +439,7 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)    setOperationAction(ISD::FDIV, MVT::v4f32, Legal);    setBooleanContents(ZeroOrNegativeOneBooleanContent); +  setBooleanVectorContents(ZeroOrNegativeOneBooleanContent); // FIXME: Is this correct?    setStackPointerRegisterToSaveRestore(SPU::R1); @@ -498,7 +499,7 @@ SPUTargetLowering::getTargetNodeName(unsigned Opcode) const  // Return the Cell SPU's SETCC result type  //===----------------------------------------------------------------------===// -MVT::SimpleValueType SPUTargetLowering::getSetCCResultType(EVT VT) const { +EVT SPUTargetLowering::getSetCCResultType(EVT VT) const {    // i8, i16 and i32 are valid SETCC result types    MVT::SimpleValueType retval; diff --git a/llvm/lib/Target/CellSPU/SPUISelLowering.h b/llvm/lib/Target/CellSPU/SPUISelLowering.h index 91bbdf26d85..aa4a1687278 100644 --- a/llvm/lib/Target/CellSPU/SPUISelLowering.h +++ b/llvm/lib/Target/CellSPU/SPUISelLowering.h @@ -107,7 +107,7 @@ namespace llvm {      virtual const char *getTargetNodeName(unsigned Opcode) const;      /// getSetCCResultType - Return the ValueType for ISD::SETCC -    virtual MVT::SimpleValueType getSetCCResultType(EVT VT) const; +    virtual EVT getSetCCResultType(EVT VT) const;      virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i32; } diff --git a/llvm/lib/Target/MBlaze/MBlazeISelLowering.cpp b/llvm/lib/Target/MBlaze/MBlazeISelLowering.cpp index 8a1774e7a27..8ec548f1437 100644 --- a/llvm/lib/Target/MBlaze/MBlazeISelLowering.cpp +++ b/llvm/lib/Target/MBlaze/MBlazeISelLowering.cpp @@ -59,6 +59,7 @@ MBlazeTargetLowering::MBlazeTargetLowering(MBlazeTargetMachine &TM)    // MBlaze does not have i1 type, so use i32 for    // setcc operations results (slt, sgt, ...).    setBooleanContents(ZeroOrOneBooleanContent); +  setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?    // Set up the register classes    addRegisterClass(MVT::i32, MBlaze::GPRRegisterClass); @@ -187,7 +188,7 @@ MBlazeTargetLowering::MBlazeTargetLowering(MBlazeTargetMachine &TM)    computeRegisterProperties();  } -MVT::SimpleValueType MBlazeTargetLowering::getSetCCResultType(EVT VT) const { +EVT MBlazeTargetLowering::getSetCCResultType(EVT VT) const {    return MVT::i32;  } diff --git a/llvm/lib/Target/MBlaze/MBlazeISelLowering.h b/llvm/lib/Target/MBlaze/MBlazeISelLowering.h index bb128da3c7c..8b49bc3de0c 100644 --- a/llvm/lib/Target/MBlaze/MBlazeISelLowering.h +++ b/llvm/lib/Target/MBlaze/MBlazeISelLowering.h @@ -102,7 +102,7 @@ namespace llvm {      virtual const char *getTargetNodeName(unsigned Opcode) const;      /// getSetCCResultType - get the ISD::SETCC result ValueType -    MVT::SimpleValueType getSetCCResultType(EVT VT) const; +    EVT getSetCCResultType(EVT VT) const;    private:      // Subtarget Info diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp index 8405789a06d..dc374315171 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -79,6 +79,7 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :    setStackPointerRegisterToSaveRestore(MSP430::SPW);    setBooleanContents(ZeroOrOneBooleanContent); +  setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?    setSchedulingPreference(Sched::Latency);    // We have post-incremented loads / stores. diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index 3e1e0090022..56fe993e2b9 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -88,6 +88,7 @@ MipsTargetLowering(MipsTargetMachine &TM)    // Mips does not have i1 type, so use i32 for    // setcc operations results (slt, sgt, ...).    setBooleanContents(ZeroOrOneBooleanContent); +  setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?    // Set up the register classes    addRegisterClass(MVT::i32, Mips::CPURegsRegisterClass); @@ -219,7 +220,7 @@ bool MipsTargetLowering::allowsUnalignedMemoryAccesses(EVT VT) const {    return SVT == MVT::i32 || SVT == MVT::i16;   } -MVT::SimpleValueType MipsTargetLowering::getSetCCResultType(EVT VT) const { +EVT MipsTargetLowering::getSetCCResultType(EVT VT) const {    return MVT::i32;  } diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h index ac3df7d3cb7..4990e7221ec 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.h +++ b/llvm/lib/Target/Mips/MipsISelLowering.h @@ -108,7 +108,7 @@ namespace llvm {      virtual const char *getTargetNodeName(unsigned Opcode) const;      /// getSetCCResultType - get the ISD::SETCC result ValueType -    MVT::SimpleValueType getSetCCResultType(EVT VT) const; +    EVT getSetCCResultType(EVT VT) const;      virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;    private: diff --git a/llvm/lib/Target/PTX/PTXISelLowering.cpp b/llvm/lib/Target/PTX/PTXISelLowering.cpp index 0961901c5f6..c8bd7bf2d84 100644 --- a/llvm/lib/Target/PTX/PTXISelLowering.cpp +++ b/llvm/lib/Target/PTX/PTXISelLowering.cpp @@ -48,6 +48,7 @@ PTXTargetLowering::PTXTargetLowering(TargetMachine &TM)    addRegisterClass(MVT::f64, PTX::RegF64RegisterClass);    setBooleanContents(ZeroOrOneBooleanContent); +  setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?    setMinFunctionAlignment(2);    //////////////////////////////////// @@ -106,7 +107,7 @@ PTXTargetLowering::PTXTargetLowering(TargetMachine &TM)    computeRegisterProperties();  } -MVT::SimpleValueType PTXTargetLowering::getSetCCResultType(EVT VT) const { +EVT PTXTargetLowering::getSetCCResultType(EVT VT) const {    return MVT::i1;  } diff --git a/llvm/lib/Target/PTX/PTXISelLowering.h b/llvm/lib/Target/PTX/PTXISelLowering.h index f99ac7bc789..3112b03d4b1 100644 --- a/llvm/lib/Target/PTX/PTXISelLowering.h +++ b/llvm/lib/Target/PTX/PTXISelLowering.h @@ -71,7 +71,7 @@ class PTXTargetLowering : public TargetLowering {                  DebugLoc dl, SelectionDAG &DAG,                  SmallVectorImpl<SDValue> &InVals) const; -    virtual MVT::SimpleValueType getSetCCResultType(EVT VT) const; +    virtual EVT getSetCCResultType(EVT VT) const;    private:      SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 39e6c2412f6..cf9f27dda9e 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -370,6 +370,7 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)    setOperationAction(ISD::ATOMIC_STORE, MVT::i32, Expand);    setBooleanContents(ZeroOrOneBooleanContent); +  setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?    if (TM.getSubtarget<PPCSubtarget>().isPPC64()) {      setStackPointerRegisterToSaveRestore(PPC::X1); @@ -469,7 +470,7 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {    }  } -MVT::SimpleValueType PPCTargetLowering::getSetCCResultType(EVT VT) const { +EVT PPCTargetLowering::getSetCCResultType(EVT VT) const {    return MVT::i32;  } diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h index 602f70abfc4..5f825bdfd32 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.h +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h @@ -246,7 +246,7 @@ namespace llvm {      virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i32; }      /// getSetCCResultType - Return the ISD::SETCC ValueType -    virtual MVT::SimpleValueType getSetCCResultType(EVT VT) const; +    virtual EVT getSetCCResultType(EVT VT) const;      /// getPreIndexedAddressParts - returns true by value, base pointer and      /// offset pointer and addressing mode by reference if the node's address diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp index 871c2972a8c..48ca99ff9ea 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -81,6 +81,7 @@ SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) :    setSchedulingPreference(Sched::RegPressure);    setBooleanContents(ZeroOrOneBooleanContent); +  setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?    setOperationAction(ISD::BR_JT,            MVT::Other, Expand);    setOperationAction(ISD::BRCOND,           MVT::Other, Expand); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index d220c59430a..1ed35d88c3c 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -181,6 +181,8 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)    // X86 is weird, it always uses i8 for shift amounts and setcc results.    setBooleanContents(ZeroOrOneBooleanContent); +  // X86-SSE is even stranger. It uses -1 or 0 for vector masks. +  setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);    // For 64-bit since we have so many registers use the ILP scheduler, for    // 32-bit code use the register pressure specific scheduling. @@ -710,7 +712,7 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)      setOperationAction(ISD::ROTL, (MVT::SimpleValueType)VT, Expand);      setOperationAction(ISD::ROTR, (MVT::SimpleValueType)VT, Expand);      setOperationAction(ISD::BSWAP, (MVT::SimpleValueType)VT, Expand); -    setOperationAction(ISD::VSETCC, (MVT::SimpleValueType)VT, Expand); +    setOperationAction(ISD::SETCC, (MVT::SimpleValueType)VT, Expand);      setOperationAction(ISD::FLOG, (MVT::SimpleValueType)VT, Expand);      setOperationAction(ISD::FLOG2, (MVT::SimpleValueType)VT, Expand);      setOperationAction(ISD::FLOG10, (MVT::SimpleValueType)VT, Expand); @@ -787,7 +789,7 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)      setOperationAction(ISD::VECTOR_SHUFFLE,     MVT::v4f32, Custom);      setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Custom);      setOperationAction(ISD::SELECT,             MVT::v4f32, Custom); -    setOperationAction(ISD::VSETCC,             MVT::v4f32, Custom); +    setOperationAction(ISD::SETCC,              MVT::v4f32, Custom);    }    if (!UseSoftFloat && Subtarget->hasXMMInt()) { @@ -817,10 +819,10 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)      setOperationAction(ISD::FSQRT,              MVT::v2f64, Legal);      setOperationAction(ISD::FNEG,               MVT::v2f64, Custom); -    setOperationAction(ISD::VSETCC,             MVT::v2f64, Custom); -    setOperationAction(ISD::VSETCC,             MVT::v16i8, Custom); -    setOperationAction(ISD::VSETCC,             MVT::v8i16, Custom); -    setOperationAction(ISD::VSETCC,             MVT::v4i32, Custom); +    setOperationAction(ISD::SETCC,              MVT::v2f64, Custom); +    setOperationAction(ISD::SETCC,              MVT::v16i8, Custom); +    setOperationAction(ISD::SETCC,              MVT::v8i16, Custom); +    setOperationAction(ISD::SETCC,              MVT::v4i32, Custom);      setOperationAction(ISD::SCALAR_TO_VECTOR,   MVT::v16i8, Custom);      setOperationAction(ISD::SCALAR_TO_VECTOR,   MVT::v8i16, Custom); @@ -950,7 +952,7 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)    }    if (Subtarget->hasSSE42() || Subtarget->hasAVX()) -    setOperationAction(ISD::VSETCC,             MVT::v2i64, Custom); +    setOperationAction(ISD::SETCC,             MVT::v2i64, Custom);    if (!UseSoftFloat && Subtarget->hasAVX()) {      addRegisterClass(MVT::v32i8,  X86::VR256RegisterClass); @@ -1002,10 +1004,10 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)      setOperationAction(ISD::SRA,               MVT::v8i32, Custom);      setOperationAction(ISD::SRA,               MVT::v16i16, Custom); -    setOperationAction(ISD::VSETCC,            MVT::v32i8, Custom); -    setOperationAction(ISD::VSETCC,            MVT::v16i16, Custom); -    setOperationAction(ISD::VSETCC,            MVT::v8i32, Custom); -    setOperationAction(ISD::VSETCC,            MVT::v4i64, Custom); +    setOperationAction(ISD::SETCC,             MVT::v32i8, Custom); +    setOperationAction(ISD::SETCC,             MVT::v16i16, Custom); +    setOperationAction(ISD::SETCC,             MVT::v8i32, Custom); +    setOperationAction(ISD::SETCC,             MVT::v4i64, Custom);      setOperationAction(ISD::SELECT,            MVT::v4f64, Custom);      setOperationAction(ISD::SELECT,            MVT::v4i64, Custom); @@ -1145,8 +1147,9 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)  } -MVT::SimpleValueType X86TargetLowering::getSetCCResultType(EVT VT) const { -  return MVT::i8; +EVT X86TargetLowering::getSetCCResultType(EVT VT) const { +  if (!VT.isVector()) return MVT::i8; +  return VT.changeVectorElementTypeToInteger();  } @@ -8319,6 +8322,9 @@ SDValue X86TargetLowering::LowerToBT(SDValue And, ISD::CondCode CC,  }  SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { + +  if (Op.getValueType().isVector()) return LowerVSETCC(Op, DAG); +    assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer");    SDValue Op0 = Op.getOperand(0);    SDValue Op1 = Op.getOperand(1); @@ -8374,7 +8380,7 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {  static SDValue Lower256IntVETCC(SDValue Op, SelectionDAG &DAG) {    EVT VT = Op.getValueType(); -  assert(VT.getSizeInBits() == 256 && Op.getOpcode() == ISD::VSETCC && +  assert(VT.getSizeInBits() == 256 && Op.getOpcode() == ISD::SETCC &&           "Unsupported value type for operation");    int NumElems = VT.getVectorNumElements(); @@ -10038,7 +10044,6 @@ SDValue X86TargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op, SelectionDAG &DAG)    SDNode* Node = Op.getNode();    EVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT();    EVT VT = Node->getValueType(0); -    if (Subtarget->hasSSE2() && VT.isVector()) {      unsigned BitsDiff = VT.getScalarType().getSizeInBits() -                          ExtraVT.getScalarType().getSizeInBits(); @@ -10344,7 +10349,6 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {    case ISD::FCOPYSIGN:          return LowerFCOPYSIGN(Op, DAG);    case ISD::FGETSIGN:           return LowerFGETSIGN(Op, DAG);    case ISD::SETCC:              return LowerSETCC(Op, DAG); -  case ISD::VSETCC:             return LowerVSETCC(Op, DAG);    case ISD::SELECT:             return LowerSELECT(Op, DAG);    case ISD::BRCOND:             return LowerBRCOND(Op, DAG);    case ISD::JumpTable:          return LowerJumpTable(Op, DAG); diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index e83fea95cba..4d0e66a1e84 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -572,8 +572,8 @@ namespace llvm {      /// DAG node.      virtual const char *getTargetNodeName(unsigned Opcode) const; -    /// getSetCCResultType - Return the ISD::SETCC ValueType -    virtual MVT::SimpleValueType getSetCCResultType(EVT VT) const; +    /// getSetCCResultType - Return the value type to use for ISD::SETCC. +    virtual EVT getSetCCResultType(EVT VT) const;      /// computeMaskedBitsForTargetNode - Determine which of the bits specified      /// in Mask are known to be either zero or one and return them in the diff --git a/llvm/lib/Target/XCore/XCoreISelLowering.cpp b/llvm/lib/Target/XCore/XCoreISelLowering.cpp index 3926a7f87f4..42dfdb73554 100644 --- a/llvm/lib/Target/XCore/XCoreISelLowering.cpp +++ b/llvm/lib/Target/XCore/XCoreISelLowering.cpp @@ -81,6 +81,7 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM)    // Use i32 for setcc operations results (slt, sgt, ...).    setBooleanContents(ZeroOrOneBooleanContent); +  setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?    // XCore does not have the NodeTypes below.    setOperationAction(ISD::BR_CC,     MVT::Other, Expand); diff --git a/llvm/lib/VMCore/ValueTypes.cpp b/llvm/lib/VMCore/ValueTypes.cpp index 525228bcd85..e13bd7df737 100644 --- a/llvm/lib/VMCore/ValueTypes.cpp +++ b/llvm/lib/VMCore/ValueTypes.cpp @@ -19,6 +19,12 @@  #include "llvm/Support/ErrorHandling.h"  using namespace llvm; +EVT EVT::changeExtendedVectorElementTypeToInteger() const { +  LLVMContext &Context = LLVMTy->getContext(); +  EVT IntTy = getIntegerVT(Context, getVectorElementType().getSizeInBits()); +  return getVectorVT(Context, IntTy, getVectorNumElements()); +} +  EVT EVT::getExtendedIntegerVT(LLVMContext &Context, unsigned BitWidth) {    EVT VT;    VT.LLVMTy = IntegerType::get(Context, BitWidth);  | 

