[PATCH] Make it possible for ints/floats to return different values from getBooleanContents()

Tom Stellard tom at stellard.net
Fri Jul 4 08:29:40 PDT 2014


On Fri, Jul 04, 2014 at 09:32:30AM +0000, Daniel Sanders wrote:
> On MIPS32r6/MIPS64r6, floating point comparisons return 0 or -1 but integer
> comparisons return 0 or 1.
> 

On the older R600 subtargets, floating-point comparisons can return
either 0.0f and 1.0f  or 0 and -1 depending on the instruction.

We currently implement this by lowering SETCC to SELECT_CC and
setting the True/False operands to use the correct boolean values.

Do you have any sense for how your changes may affect these subtargets?
I'm guessing we probably want to use ZeroOrNegativeOneBoolean contents
for floating-point comparisons, but I'm not sure.

-Tom

> Updated the various uses of getBooleanContents. Two simplifications had to be
> disabled when float and int boolean contents differ:
> - ScalarizeVecRes_VSELECT except when the kind of boolean contents is trivially
>   discoverable (i.e. when the condition of the VSELECT is a SETCC node).
> - visitVSELECT (select C, 0, 1) -> (xor C, 1).
>   Come to think of it, this one could test for the common case of 'C'
>   being a SETCC too.
> 
> Preserved existing behaviour for all other targets and updated the affected
> MIPS32r6/MIPS64r6 tests. This also fixes the pi benchmark where the 'low'
> variable was counting in the wrong direction because it thought it could simply
> add the result of the comparison.
> 
> http://reviews.llvm.org/D4389
> 
> Files:
>   include/llvm/CodeGen/SelectionDAG.h
>   include/llvm/Target/TargetLowering.h
>   lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>   lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
>   lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
>   lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
>   lib/CodeGen/SelectionDAG/LegalizeTypes.h
>   lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
>   lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
>   lib/CodeGen/SelectionDAG/SelectionDAG.cpp
>   lib/CodeGen/SelectionDAG/TargetLowering.cpp
>   lib/CodeGen/TargetLoweringBase.cpp
>   lib/Target/AArch64/AArch64ISelLowering.cpp
>   lib/Target/MSP430/MSP430ISelLowering.cpp
>   lib/Target/Mips/MipsISelLowering.cpp
>   lib/Target/NVPTX/NVPTXISelLowering.cpp
>   lib/Target/PowerPC/PPCISelLowering.cpp
>   lib/Target/R600/R600ISelLowering.cpp
>   lib/Target/SystemZ/SystemZISelLowering.cpp
>   lib/Target/X86/X86ISelLowering.cpp
>   lib/Target/XCore/XCoreISelLowering.cpp
>   test/CodeGen/Mips/fcmp.ll
>   test/CodeGen/Mips/select.ll

> Index: include/llvm/CodeGen/SelectionDAG.h
> ===================================================================
> --- include/llvm/CodeGen/SelectionDAG.h
> +++ include/llvm/CodeGen/SelectionDAG.h
> @@ -564,8 +564,8 @@
>  
>    /// getBoolExtOrTrunc - Convert Op, which must be of integer type, to the
>    /// integer type VT, by using an extension appropriate for the target's
> -  /// BooleanContent or truncating it.
> -  SDValue getBoolExtOrTrunc(SDValue Op, SDLoc SL, EVT VT);
> +  /// BooleanContent for type OpVT or truncating it.
> +  SDValue getBoolExtOrTrunc(SDValue Op, SDLoc SL, EVT VT, EVT OpVT);
>  
>    /// getNOT - Create a bitwise NOT operation as (XOR Val, -1).
>    SDValue getNOT(SDLoc DL, SDValue Val, EVT VT);
> Index: include/llvm/Target/TargetLowering.h
> ===================================================================
> --- include/llvm/Target/TargetLowering.h
> +++ include/llvm/Target/TargetLowering.h
> @@ -279,10 +279,23 @@
>    /// 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 {
> +  ///
> +  /// Some cpus also treat floating point types the same way as they treat
> +  /// vectors instead of the way they treat scalars.
> +  BooleanContent getBooleanContentsOLD(bool isVec) const {
>      return isVec ? BooleanVectorContents : BooleanContents;
>    }
>  
> +  BooleanContent getBooleanContents(bool isVec, bool isFloat) const {
> +    if (isVec)
> +      return BooleanVectorContents;
> +    return isFloat ? BooleanFloatContents : BooleanContents;
> +  }
> +
> +  BooleanContent getBooleanContents(EVT Type) const {
> +    return getBooleanContents(Type.isVector(), Type.isFloatingPoint());
> +  }
> +
>    /// Return target scheduling preference.
>    Sched::Preference getSchedulingPreference() const {
>      return SchedPreferenceInfo;
> @@ -942,6 +955,10 @@
>    /// wider type.  See getBooleanContents.
>    void setBooleanContents(BooleanContent Ty) { BooleanContents = Ty; }
>  
> +  /// Specify how the target extends the result of a floating point boolean
> +  /// value from i1 to a wider type.  See getBooleanContents.
> +  void setBooleanFloatContents(BooleanContent Ty) { BooleanFloatContents = Ty; }
> +
>    /// 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) {
> @@ -1484,6 +1501,10 @@
>    /// a type wider than i1. See getBooleanContents.
>    BooleanContent BooleanContents;
>  
> +  /// Information about the contents of the high-bits in boolean values held in
> +  /// a type wider than i1. See getBooleanContents.
> +  BooleanContent BooleanFloatContents;
> +
>    /// Information about the contents of the high-bits in boolean vector values
>    /// when the element type is wider than i1. See getBooleanContents.
>    BooleanContent BooleanVectorContents;
> Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> ===================================================================
> --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> @@ -3954,14 +3954,14 @@
>      // If setcc produces all-one true value then:
>      // (shl (and (setcc) N01CV) N1CV) -> (and (setcc) N01CV<<N1CV)
>      if (N1CV && N1CV->isConstant()) {
> -      if (N0.getOpcode() == ISD::AND &&
> -          TLI.getBooleanContents(true) ==
> -          TargetLowering::ZeroOrNegativeOneBooleanContent) {
> +      if (N0.getOpcode() == ISD::AND) {
>          SDValue N00 = N0->getOperand(0);
>          SDValue N01 = N0->getOperand(1);
>          BuildVectorSDNode *N01CV = dyn_cast<BuildVectorSDNode>(N01);
>  
> -        if (N01CV && N01CV->isConstant() && N00.getOpcode() == ISD::SETCC) {
> +        if (N01CV && N01CV->isConstant() && N00.getOpcode() == ISD::SETCC &&
> +            TLI.getBooleanContents(N00.getOperand(0).getValueType()) ==
> +                TargetLowering::ZeroOrNegativeOneBooleanContent) {
>            SDValue C = DAG.FoldConstantArithmetic(ISD::SHL, VT, N01CV, N1CV);
>            if (C.getNode())
>              return DAG.getNode(ISD::AND, SDLoc(N), VT, N00, C);
> @@ -4520,11 +4520,14 @@
>    if (VT == MVT::i1 && N1C && N1C->getAPIntValue() == 1)
>      return DAG.getNode(ISD::OR, SDLoc(N), VT, N0, N2);
>    // fold (select C, 0, 1) -> (xor C, 1)
> +  // We can't do this reliably if integer based booleans have different contents
> +  // to floating point based booleans.
>    if (VT.isInteger() &&
> -      (VT0 == MVT::i1 ||
> -       (VT0.isInteger() &&
> -        TLI.getBooleanContents(false) ==
> -        TargetLowering::ZeroOrOneBooleanContent)) &&
> +      (VT0 == MVT::i1 || (VT0.isInteger() &&
> +                          TLI.getBooleanContents(false, false) ==
> +                              TLI.getBooleanContents(false, true) &&
> +                          TLI.getBooleanContents(false, false) ==
> +                              TargetLowering::ZeroOrOneBooleanContent)) &&
>        N1C && N2C && N1C->isNullValue() && N2C->getAPIntValue() == 1) {
>      SDValue XORNode;
>      if (VT == VT0)
> @@ -5073,12 +5076,12 @@
>    }
>  
>    if (N0.getOpcode() == ISD::SETCC) {
> +    EVT N0VT = N0.getOperand(0).getValueType();
>      // sext(setcc) -> sext_in_reg(vsetcc) for vectors.
>      // Only do this before legalize for now.
>      if (VT.isVector() && !LegalOperations &&
> -        TLI.getBooleanContents(true) ==
> -          TargetLowering::ZeroOrNegativeOneBooleanContent) {
> -      EVT N0VT = N0.getOperand(0).getValueType();
> +        TLI.getBooleanContents(N0VT) ==
> +            TargetLowering::ZeroOrNegativeOneBooleanContent) {
>        // On some architectures (such as SSE/NEON/etc) the SETCC result type is
>        // of the same size as the compared operands. Only optimize sext(setcc())
>        // if this is the case.
> @@ -11190,8 +11193,8 @@
>  
>    // fold select C, 16, 0 -> shl C, 4
>    if (N2C && N3C && N3C->isNullValue() && N2C->getAPIntValue().isPowerOf2() &&
> -    TLI.getBooleanContents(N0.getValueType().isVector()) ==
> -      TargetLowering::ZeroOrOneBooleanContent) {
> +      TLI.getBooleanContents(N0.getValueType()) ==
> +          TargetLowering::ZeroOrOneBooleanContent) {
>  
>      // If the caller doesn't want us to simplify this into a zext of a compare,
>      // don't do it.
> Index: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
> ===================================================================
> --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
> +++ lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
> @@ -3761,7 +3761,7 @@
>      SDValue SumSignNE = DAG.getSetCC(dl, OType, LHSSign, SumSign, ISD::SETNE);
>  
>      SDValue Cmp = DAG.getNode(ISD::AND, dl, OType, SignsMatch, SumSignNE);
> -    Results.push_back(DAG.getBoolExtOrTrunc(Cmp, dl, ResultType));
> +    Results.push_back(DAG.getBoolExtOrTrunc(Cmp, dl, ResultType, ResultType));
>      break;
>    }
>    case ISD::UADDO:
> @@ -3779,7 +3779,7 @@
>        = Node->getOpcode() == ISD::UADDO ? ISD::SETULT : ISD::SETUGT;
>      SDValue SetCC = DAG.getSetCC(dl, SetCCType, Sum, LHS, CC);
>  
> -    Results.push_back(DAG.getBoolExtOrTrunc(SetCC, dl, ResultType));
> +    Results.push_back(DAG.getBoolExtOrTrunc(SetCC, dl, ResultType, ResultType));
>      break;
>    }
>    case ISD::UMULO:
> @@ -3969,7 +3969,7 @@
>      // illegal; expand it into a SELECT_CC.
>      EVT VT = Node->getValueType(0);
>      int TrueValue;
> -    switch (TLI.getBooleanContents(VT.isVector())) {
> +    switch (TLI.getBooleanContents(Tmp1->getValueType(0))) {
>      case TargetLowering::ZeroOrOneBooleanContent:
>      case TargetLowering::UndefinedBooleanContent:
>        TrueValue = 1;
> Index: lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
> ===================================================================
> --- lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
> +++ lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
> @@ -519,7 +519,7 @@
>    EVT OpTy = N->getOperand(1).getValueType();
>  
>    // Promote all the way up to the canonical SetCC type.
> -  Mask = PromoteTargetBoolean(Mask, getSetCCResultType(OpTy));
> +  Mask = PromoteTargetBoolean(Mask, OpTy);
>    SDValue LHS = GetPromotedInteger(N->getOperand(1));
>    SDValue RHS = GetPromotedInteger(N->getOperand(2));
>    return DAG.getNode(ISD::VSELECT, SDLoc(N),
> @@ -919,8 +919,7 @@
>    assert(OpNo == 1 && "only know how to promote condition");
>  
>    // Promote all the way up to the canonical SetCC type.
> -  EVT SVT = getSetCCResultType(MVT::Other);
> -  SDValue Cond = PromoteTargetBoolean(N->getOperand(1), SVT);
> +  SDValue Cond = PromoteTargetBoolean(N->getOperand(1), MVT::Other);
>  
>    // The chain (Op#0) and basic block destination (Op#2) are always legal types.
>    return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Cond,
> @@ -1013,9 +1012,8 @@
>    EVT OpTy = N->getOperand(1).getValueType();
>  
>    // Promote all the way up to the canonical SetCC type.
> -  EVT SVT = getSetCCResultType(N->getOpcode() == ISD::SELECT ?
> -                                   OpTy.getScalarType() : OpTy);
> -  Cond = PromoteTargetBoolean(Cond, SVT);
> +  EVT OpVT = N->getOpcode() == ISD::SELECT ? OpTy.getScalarType() : OpTy;
> +  Cond = PromoteTargetBoolean(Cond, OpVT);
>  
>    return SDValue(DAG.UpdateNodeOperands(N, Cond, N->getOperand(1),
>                                          N->getOperand(2)), 0);
> Index: lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
> ===================================================================
> --- lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
> +++ lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
> @@ -1065,11 +1065,14 @@
>  /// PromoteTargetBoolean - Promote the given target boolean to a target boolean
>  /// of the given type.  A target boolean is an integer value, not necessarily of
>  /// type i1, the bits of which conform to getBooleanContents.
> -SDValue DAGTypeLegalizer::PromoteTargetBoolean(SDValue Bool, EVT VT) {
> +///
> +/// ValVT is the type of values that produced the boolean.
> +SDValue DAGTypeLegalizer::PromoteTargetBoolean(SDValue Bool, EVT ValVT) {
>    SDLoc dl(Bool);
> +  EVT BoolVT = getSetCCResultType(ValVT);
>    ISD::NodeType ExtendCode =
> -    TargetLowering::getExtendForContent(TLI.getBooleanContents(VT.isVector()));
> -  return DAG.getNode(ExtendCode, dl, VT, Bool);
> +      TargetLowering::getExtendForContent(TLI.getBooleanContents(ValVT));
> +  return DAG.getNode(ExtendCode, dl, BoolVT, Bool);
>  }
>  
>  /// SplitInteger - Return the lower LoVT bits of Op in Lo and the upper HiVT
> Index: lib/CodeGen/SelectionDAG/LegalizeTypes.h
> ===================================================================
> --- lib/CodeGen/SelectionDAG/LegalizeTypes.h
> +++ lib/CodeGen/SelectionDAG/LegalizeTypes.h
> @@ -167,7 +167,7 @@
>                                                   SDNode *Node, bool isSigned);
>    std::pair<SDValue, SDValue> ExpandAtomic(SDNode *Node);
>  
> -  SDValue PromoteTargetBoolean(SDValue Bool, EVT VT);
> +  SDValue PromoteTargetBoolean(SDValue Bool, EVT ValVT);
>    void ReplaceValueWith(SDValue From, SDValue To);
>    void SplitInteger(SDValue Op, SDValue &Lo, SDValue &Hi);
>    void SplitInteger(SDValue Op, EVT LoVT, EVT HiVT,
> Index: lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
> ===================================================================
> --- lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
> +++ lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
> @@ -751,9 +751,9 @@
>    // FIXME: Sign extend 1 to all ones if thats legal on the target.
>    if (TLI.getOperationAction(ISD::AND, VT) == TargetLowering::Expand ||
>        TLI.getOperationAction(ISD::XOR, VT) == TargetLowering::Expand ||
> -      TLI.getOperationAction(ISD::OR,  VT) == TargetLowering::Expand ||
> -      TLI.getBooleanContents(true) !=
> -      TargetLowering::ZeroOrNegativeOneBooleanContent)
> +      TLI.getOperationAction(ISD::OR, VT) == TargetLowering::Expand ||
> +      TLI.getBooleanContents(Op1.getValueType()) !=
> +          TargetLowering::ZeroOrNegativeOneBooleanContent)
>      return DAG.UnrollVectorOp(Op.getNode());
>  
>    // If the mask and the type are different sizes, unroll the vector op. This
> Index: lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
> ===================================================================
> --- lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
> +++ lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
> @@ -257,8 +257,24 @@
>  SDValue DAGTypeLegalizer::ScalarizeVecRes_VSELECT(SDNode *N) {
>    SDValue Cond = GetScalarizedVector(N->getOperand(0));
>    SDValue LHS = GetScalarizedVector(N->getOperand(1));
> -  TargetLowering::BooleanContent ScalarBool = TLI.getBooleanContents(false);
> -  TargetLowering::BooleanContent VecBool = TLI.getBooleanContents(true);
> +  TargetLowering::BooleanContent ScalarBool =
> +      TLI.getBooleanContents(false, false);
> +  TargetLowering::BooleanContent VecBool = TLI.getBooleanContents(true, false);
> +
> +  // If integer and float booleans have different contents then we can't
> +  // reliably optimize in all cases.
> +  if (TLI.getBooleanContents(false, false) !=
> +      TLI.getBooleanContents(false, true)) {
> +    // At least try the common case where the boolean is generated by a
> +    // comparison.
> +    if (Cond->getOpcode() == ISD::SETCC) {
> +      EVT OpVT = Cond->getOperand(0)->getValueType(0);
> +      ScalarBool = TLI.getBooleanContents(OpVT.getScalarType());
> +      VecBool = TLI.getBooleanContents(OpVT);
> +    } else
> +      ScalarBool = TargetLowering::UndefinedBooleanContent;
> +  }
> +
>    if (ScalarBool != VecBool) {
>      EVT CondVT = Cond.getValueType();
>      switch (ScalarBool) {
> @@ -357,7 +373,7 @@
>    // Vectors may have a different boolean contents to scalars.  Promote the
>    // value appropriately.
>    ISD::NodeType ExtendCode =
> -    TargetLowering::getExtendForContent(TLI.getBooleanContents(true));
> +      TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT));
>    return DAG.getNode(ExtendCode, DL, NVT, Res);
>  }
>  
> Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> ===================================================================
> --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> @@ -1012,11 +1012,12 @@
>      getNode(ISD::TRUNCATE, DL, VT, Op);
>  }
>  
> -SDValue SelectionDAG::getBoolExtOrTrunc(SDValue Op, SDLoc SL, EVT VT) {
> +SDValue SelectionDAG::getBoolExtOrTrunc(SDValue Op, SDLoc SL, EVT VT,
> +                                        EVT OpVT) {
>    if (VT.bitsLE(Op.getValueType()))
>      return getNode(ISD::TRUNCATE, SL, VT, Op);
>  
> -  TargetLowering::BooleanContent BType = TLI->getBooleanContents(VT.isVector());
> +  TargetLowering::BooleanContent BType = TLI->getBooleanContents(OpVT);
>    return getNode(TLI->getExtendForContent(BType), SL, VT, Op);
>  }
>  
> @@ -1044,7 +1045,7 @@
>  SDValue SelectionDAG::getLogicalNOT(SDLoc DL, SDValue Val, EVT VT) {
>    EVT EltVT = VT.getScalarType();
>    SDValue TrueValue;
> -  switch (TLI->getBooleanContents(VT.isVector())) {
> +  switch (TLI->getBooleanContents(VT)) {
>      case TargetLowering::ZeroOrOneBooleanContent:
>      case TargetLowering::UndefinedBooleanContent:
>        TrueValue = getConstant(1, VT);
> @@ -1734,7 +1735,8 @@
>    case ISD::SETTRUE:
>    case ISD::SETTRUE2: {
>      const TargetLowering *TLI = TM.getTargetLowering();
> -    TargetLowering::BooleanContent Cnt = TLI->getBooleanContents(VT.isVector());
> +    TargetLowering::BooleanContent Cnt =
> +        TLI->getBooleanContents(N1->getValueType(0));
>      return getConstant(
>          Cnt == TargetLowering::ZeroOrNegativeOneBooleanContent ? -1ULL : 1, VT);
>    }
> @@ -1965,11 +1967,20 @@
>    case ISD::UMULO:
>      if (Op.getResNo() != 1)
>        break;
> -    // The boolean result conforms to getBooleanContents.  Fall through.
> +    // The boolean result conforms to getBooleanContents.
> +    // If we know the result of a setcc has the top bits zero, use this info.
> +    // We know that we have an integer-based boolean since these operations
> +    // are only available for integer.
> +    if (TLI->getBooleanContents(Op.getValueType().isVector(), false) ==
> +            TargetLowering::ZeroOrOneBooleanContent &&
> +        BitWidth > 1)
> +      KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - 1);
> +    break;
>    case ISD::SETCC:
>      // If we know the result of a setcc has the top bits zero, use this info.
> -    if (TLI->getBooleanContents(Op.getValueType().isVector()) ==
> -        TargetLowering::ZeroOrOneBooleanContent && BitWidth > 1)
> +    if (TLI->getBooleanContents(Op.getOperand(0).getValueType()) ==
> +            TargetLowering::ZeroOrOneBooleanContent &&
> +        BitWidth > 1)
>        KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - 1);
>      break;
>    case ISD::SHL:
> @@ -2368,9 +2379,16 @@
>      if (Op.getResNo() != 1)
>        break;
>      // The boolean result conforms to getBooleanContents.  Fall through.
> +    // If setcc returns 0/-1, all bits are sign bits.
> +    // We know that we have an integer-based boolean since these operations
> +    // are only available for integer.
> +    if (TLI->getBooleanContents(Op.getValueType().isVector(), false) ==
> +        TargetLowering::ZeroOrNegativeOneBooleanContent)
> +      return VTBits;
> +    break;
>    case ISD::SETCC:
>      // If setcc returns 0/-1, all bits are sign bits.
> -    if (TLI->getBooleanContents(Op.getValueType().isVector()) ==
> +    if (TLI->getBooleanContents(Op.getOperand(0).getValueType()) ==
>          TargetLowering::ZeroOrNegativeOneBooleanContent)
>        return VTBits;
>      break;
> Index: lib/CodeGen/SelectionDAG/TargetLowering.cpp
> ===================================================================
> --- lib/CodeGen/SelectionDAG/TargetLowering.cpp
> +++ lib/CodeGen/SelectionDAG/TargetLowering.cpp
> @@ -1150,18 +1150,16 @@
>    if (!N)
>      return false;
>  
> -  bool IsVec = false;
>    const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
>    if (!CN) {
>      const BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N);
>      if (!BV)
>        return false;
>  
> -    IsVec = true;
>      CN = BV->getConstantSplatValue();
>    }
>  
> -  switch (getBooleanContents(IsVec)) {
> +  switch (getBooleanContents(N->getValueType(0))) {
>    case UndefinedBooleanContent:
>      return CN->getAPIntValue()[0];
>    case ZeroOrOneBooleanContent:
> @@ -1177,18 +1175,16 @@
>    if (!N)
>      return false;
>  
> -  bool IsVec = false;
>    const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
>    if (!CN) {
>      const BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N);
>      if (!BV)
>        return false;
>  
> -    IsVec = true;
>      CN = BV->getConstantSplatValue();
>    }
>  
> -  if (getBooleanContents(IsVec) == UndefinedBooleanContent)
> +  if (getBooleanContents(N->getValueType(0)) == UndefinedBooleanContent)
>      return !CN->getAPIntValue()[0];
>  
>    return CN->isNullValue();
> @@ -1209,7 +1205,8 @@
>    case ISD::SETFALSE2: return DAG.getConstant(0, VT);
>    case ISD::SETTRUE:
>    case ISD::SETTRUE2: {
> -    TargetLowering::BooleanContent Cnt = getBooleanContents(VT.isVector());
> +    TargetLowering::BooleanContent Cnt =
> +        getBooleanContents(N0->getValueType(0));
>      return DAG.getConstant(
>          Cnt == TargetLowering::ZeroOrNegativeOneBooleanContent ? -1ULL : 1, VT);
>    }
> @@ -1416,7 +1413,7 @@
>  
>            SDValue NewSetCC = DAG.getSetCC(dl, NewSetCCVT, N0.getOperand(0),
>                                            NewConst, Cond);
> -          return DAG.getBoolExtOrTrunc(NewSetCC, dl, VT);
> +          return DAG.getBoolExtOrTrunc(NewSetCC, dl, VT, N0.getValueType());
>          }
>          break;
>        }
> @@ -1500,7 +1497,8 @@
>          }
>        } else if (N1C->getAPIntValue() == 1 &&
>                   (VT == MVT::i1 ||
> -                  getBooleanContents(false) == ZeroOrOneBooleanContent)) {
> +                  getBooleanContents(N0->getValueType(0)) ==
> +                      ZeroOrOneBooleanContent)) {
>          SDValue Op0 = N0;
>          if (Op0.getOpcode() == ISD::TRUNCATE)
>            Op0 = Op0.getOperand(0);
> @@ -1771,7 +1769,7 @@
>      // The sext(setcc()) => setcc() optimization relies on the appropriate
>      // constant being emitted.
>      uint64_t EqVal = 0;
> -    switch (getBooleanContents(N0.getValueType().isVector())) {
> +    switch (getBooleanContents(N0.getValueType())) {
>      case UndefinedBooleanContent:
>      case ZeroOrOneBooleanContent:
>        EqVal = ISD::isTrueWhenEqual(Cond);
> Index: lib/CodeGen/TargetLoweringBase.cpp
> ===================================================================
> --- lib/CodeGen/TargetLoweringBase.cpp
> +++ lib/CodeGen/TargetLoweringBase.cpp
> @@ -690,6 +690,7 @@
>    ExceptionPointerRegister = 0;
>    ExceptionSelectorRegister = 0;
>    BooleanContents = UndefinedBooleanContent;
> +  BooleanFloatContents = UndefinedBooleanContent;
>    BooleanVectorContents = UndefinedBooleanContent;
>    SchedPreferenceInfo = Sched::ILP;
>    JumpBufSize = 0;
> Index: lib/Target/AArch64/AArch64ISelLowering.cpp
> ===================================================================
> --- lib/Target/AArch64/AArch64ISelLowering.cpp
> +++ lib/Target/AArch64/AArch64ISelLowering.cpp
> @@ -81,6 +81,7 @@
>    // AArch64 doesn't have comparisons which set GPRs or setcc instructions, so
>    // we have to make something up. Arbitrarily, choose ZeroOrOne.
>    setBooleanContents(ZeroOrOneBooleanContent);
> +  setBooleanFloatContents(ZeroOrOneBooleanContent);
>    // When comparing vectors the result sets the different elements in the
>    // vector to all-one or all-zero.
>    setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
> Index: lib/Target/MSP430/MSP430ISelLowering.cpp
> ===================================================================
> --- lib/Target/MSP430/MSP430ISelLowering.cpp
> +++ lib/Target/MSP430/MSP430ISelLowering.cpp
> @@ -74,6 +74,7 @@
>  
>    setStackPointerRegisterToSaveRestore(MSP430::SPW);
>    setBooleanContents(ZeroOrOneBooleanContent);
> +  setBooleanFloatContents(ZeroOrOneBooleanContent);
>    setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
>  
>    // We have post-incremented loads / stores.
> Index: lib/Target/Mips/MipsISelLowering.cpp
> ===================================================================
> --- lib/Target/Mips/MipsISelLowering.cpp
> +++ lib/Target/Mips/MipsISelLowering.cpp
> @@ -214,7 +214,12 @@
>    // Mips does not have i1 type, so use i32 for
>    // setcc operations results (slt, sgt, ...).
>    setBooleanContents(ZeroOrOneBooleanContent);
> +  setBooleanFloatContents(ZeroOrOneBooleanContent);
>    setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
> +  // The cmp.cond.fmt instruction in MIPS32r6/MIPS64r6 uses 0 and -1 like MSA
> +  // does.
> +  if (Subtarget->hasMips32r6())
> +    setBooleanFloatContents(ZeroOrNegativeOneBooleanContent);
>  
>    // Load extented operations for i1 types must be promoted
>    setLoadExtAction(ISD::EXTLOAD,  MVT::i1,  Promote);
> Index: lib/Target/NVPTX/NVPTXISelLowering.cpp
> ===================================================================
> --- lib/Target/NVPTX/NVPTXISelLowering.cpp
> +++ lib/Target/NVPTX/NVPTXISelLowering.cpp
> @@ -112,6 +112,7 @@
>    MaxStoresPerMemmove = (unsigned) 0xFFFFFFFF;
>  
>    setBooleanContents(ZeroOrNegativeOneBooleanContent);
> +  setBooleanFloatContents(ZeroOrNegativeOneBooleanContent);
>    setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
>  
>    // Jump is Expensive. Don't create extra control flow for 'and', 'or'
> Index: lib/Target/PowerPC/PPCISelLowering.cpp
> ===================================================================
> --- lib/Target/PowerPC/PPCISelLowering.cpp
> +++ lib/Target/PowerPC/PPCISelLowering.cpp
> @@ -623,6 +623,7 @@
>    setOperationAction(ISD::ATOMIC_STORE, MVT::i64, Expand);
>  
>    setBooleanContents(ZeroOrOneBooleanContent);
> +  setBooleanFloatContents(ZeroOrOneBooleanContent);
>    // Altivec instructions set fields to all zeros or all ones.
>    setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
>  
> Index: lib/Target/R600/R600ISelLowering.cpp
> ===================================================================
> --- lib/Target/R600/R600ISelLowering.cpp
> +++ lib/Target/R600/R600ISelLowering.cpp
> @@ -179,6 +179,7 @@
>    }
>  
>    setBooleanContents(ZeroOrNegativeOneBooleanContent);
> +  setBooleanFloatContents(ZeroOrNegativeOneBooleanContent);
>    setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
>    setSchedulingPreference(Sched::Source);
>  }
> Index: lib/Target/SystemZ/SystemZISelLowering.cpp
> ===================================================================
> --- lib/Target/SystemZ/SystemZISelLowering.cpp
> +++ lib/Target/SystemZ/SystemZISelLowering.cpp
> @@ -110,6 +110,7 @@
>    setSchedulingPreference(Sched::RegPressure);
>  
>    setBooleanContents(ZeroOrOneBooleanContent);
> +  setBooleanFloatContents(ZeroOrOneBooleanContent);
>    setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
>  
>    // Instructions are strings of 2-byte aligned 2-byte values.
> Index: lib/Target/X86/X86ISelLowering.cpp
> ===================================================================
> --- lib/Target/X86/X86ISelLowering.cpp
> +++ lib/Target/X86/X86ISelLowering.cpp
> @@ -236,6 +236,7 @@
>  
>    // X86 is weird, it always uses i8 for shift amounts and setcc results.
>    setBooleanContents(ZeroOrOneBooleanContent);
> +  setBooleanFloatContents(ZeroOrOneBooleanContent);
>    // X86-SSE is even stranger. It uses -1 or 0 for vector masks.
>    setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
>  
> Index: lib/Target/XCore/XCoreISelLowering.cpp
> ===================================================================
> --- lib/Target/XCore/XCoreISelLowering.cpp
> +++ lib/Target/XCore/XCoreISelLowering.cpp
> @@ -87,6 +87,7 @@
>  
>    // Use i32 for setcc operations results (slt, sgt, ...).
>    setBooleanContents(ZeroOrOneBooleanContent);
> +  setBooleanFloatContents(ZeroOrOneBooleanContent);
>    setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
>  
>    // XCore does not have the NodeTypes below.
> Index: test/CodeGen/Mips/fcmp.ll
> ===================================================================
> --- test/CodeGen/Mips/fcmp.ll
> +++ test/CodeGen/Mips/fcmp.ll
> @@ -29,10 +29,12 @@
>  ; 64-C-DAG:      movt $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.eq.s $[[T0:f[0-9]+]], $f12, $f14
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.eq.s $[[T0:f[0-9]+]], $f12, $f13
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp oeq float %a, %b
>    %2 = zext i1 %1 to i32
> @@ -53,10 +55,12 @@
>  ; 64-C-DAG:      movf $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.lt.s $[[T0:f[0-9]+]], $f14, $f12
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.lt.s $[[T0:f[0-9]+]], $f13, $f12
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp ogt float %a, %b
>    %2 = zext i1 %1 to i32
> @@ -77,10 +81,12 @@
>  ; 64-C-DAG:      movf $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.le.s $[[T0:f[0-9]+]], $f14, $f12
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.le.s $[[T0:f[0-9]+]], $f13, $f12
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp oge float %a, %b
>    %2 = zext i1 %1 to i32
> @@ -101,10 +107,12 @@
>  ; 64-C-DAG:      movt $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.lt.s $[[T0:f[0-9]+]], $f12, $f14
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.lt.s $[[T0:f[0-9]+]], $f12, $f13
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp olt float %a, %b
>    %2 = zext i1 %1 to i32
> @@ -125,10 +133,12 @@
>  ; 64-C-DAG:      movt $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.le.s $[[T0:f[0-9]+]], $f12, $f14
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.le.s $[[T0:f[0-9]+]], $f12, $f13
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp ole float %a, %b
>    %2 = zext i1 %1 to i32
> @@ -150,11 +160,13 @@
>  
>  ; 32-CMP-DAG:    cmp.ueq.s $[[T0:f[0-9]+]], $f12, $f14
>  ; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> -; 32-CMP-DAG:    not $2, $[[T1]]
> +; 32-CMP-DAG:    not $[[T2:[0-9]+]], $[[T1]]
> +; 32-CMP-DAG:    andi $2, $[[T2]], 1
>  
>  ; 64-CMP-DAG:    cmp.ueq.s $[[T0:f[0-9]+]], $f12, $f13
>  ; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> -; 64-CMP-DAG:    not $2, $[[T1]]
> +; 64-CMP-DAG:    not $[[T2:[0-9]+]], $[[T1]]
> +; 64-CMP-DAG:    andi $2, $[[T2]], 1
>  
>    %1 = fcmp one float %a, %b
>    %2 = zext i1 %1 to i32
> @@ -176,11 +188,13 @@
>  
>  ; 32-CMP-DAG:    cmp.un.s $[[T0:f[0-9]+]], $f12, $f14
>  ; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> -; 32-CMP-DAG:    not $2, $[[T1]]
> +; 32-CMP-DAG:    not $[[T2:[0-9]+]], $[[T1]]
> +; 32-CMP-DAG:    andi $2, $[[T2]], 1
>  
>  ; 64-CMP-DAG:    cmp.un.s $[[T0:f[0-9]+]], $f12, $f13
>  ; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> -; 64-CMP-DAG:    not $2, $[[T1]]
> +; 64-CMP-DAG:    not $[[T2:[0-9]+]], $[[T1]]
> +; 64-CMP-DAG:    andi $2, $[[T2]], 1
>  
>    %1 = fcmp ord float %a, %b
>    %2 = zext i1 %1 to i32
> @@ -201,10 +215,12 @@
>  ; 64-C-DAG:      movt $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.ueq.s $[[T0:f[0-9]+]], $f12, $f14
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.ueq.s $[[T0:f[0-9]+]], $f12, $f13
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp ueq float %a, %b
>    %2 = zext i1 %1 to i32
> @@ -225,10 +241,12 @@
>  ; 64-C-DAG:      movf $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.ult.s $[[T0:f[0-9]+]], $f14, $f12
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.ult.s $[[T0:f[0-9]+]], $f13, $f12
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp ugt float %a, %b
>    %2 = zext i1 %1 to i32
> @@ -249,10 +267,12 @@
>  ; 64-C-DAG:      movf $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.ule.s $[[T0:f[0-9]+]], $f14, $f12
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.ule.s $[[T0:f[0-9]+]], $f13, $f12
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp uge float %a, %b
>    %2 = zext i1 %1 to i32
> @@ -273,10 +293,12 @@
>  ; 64-C-DAG:      movt $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.ult.s $[[T0:f[0-9]+]], $f12, $f14
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.ult.s $[[T0:f[0-9]+]], $f12, $f13
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp ult float %a, %b
>    %2 = zext i1 %1 to i32
> @@ -297,10 +319,12 @@
>  ; 64-C-DAG:      movt $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.ule.s $[[T0:f[0-9]+]], $f12, $f14
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.ule.s $[[T0:f[0-9]+]], $f12, $f13
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp ule float %a, %b
>    %2 = zext i1 %1 to i32
> @@ -322,11 +346,13 @@
>  
>  ; 32-CMP-DAG:    cmp.eq.s $[[T0:f[0-9]+]], $f12, $f14
>  ; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> -; 32-CMP-DAG:    not $2, $[[T1]]
> +; 32-CMP-DAG:    not $[[T2:[0-9]+]], $[[T1]]
> +; 32-CMP-DAG:    andi $2, $[[T2]], 1
>  
>  ; 64-CMP-DAG:    cmp.eq.s $[[T0:f[0-9]+]], $f12, $f13
>  ; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> -; 64-CMP-DAG:    not $2, $[[T1]]
> +; 64-CMP-DAG:    not $[[T2:[0-9]+]], $[[T1]]
> +; 64-CMP-DAG:    andi $2, $[[T2]], 1
>  
>    %1 = fcmp une float %a, %b
>    %2 = zext i1 %1 to i32
> @@ -347,10 +373,12 @@
>  ; 64-C-DAG:      movt $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.un.s $[[T0:f[0-9]+]], $f12, $f14
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.un.s $[[T0:f[0-9]+]], $f12, $f13
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp uno float %a, %b
>    %2 = zext i1 %1 to i32
> @@ -389,10 +417,12 @@
>  ; 64-C-DAG:      movt $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.eq.d $[[T0:f[0-9]+]], $f12, $f14
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.eq.d $[[T0:f[0-9]+]], $f12, $f13
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp oeq double %a, %b
>    %2 = zext i1 %1 to i32
> @@ -413,10 +443,12 @@
>  ; 64-C-DAG:      movf $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.lt.d $[[T0:f[0-9]+]], $f14, $f12
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.lt.d $[[T0:f[0-9]+]], $f13, $f12
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp ogt double %a, %b
>    %2 = zext i1 %1 to i32
> @@ -437,10 +469,12 @@
>  ; 64-C-DAG:      movf $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.le.d $[[T0:f[0-9]+]], $f14, $f12
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.le.d $[[T0:f[0-9]+]], $f13, $f12
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp oge double %a, %b
>    %2 = zext i1 %1 to i32
> @@ -461,10 +495,12 @@
>  ; 64-C-DAG:      movt $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.lt.d $[[T0:f[0-9]+]], $f12, $f14
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.lt.d $[[T0:f[0-9]+]], $f12, $f13
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp olt double %a, %b
>    %2 = zext i1 %1 to i32
> @@ -485,10 +521,12 @@
>  ; 64-C-DAG:      movt $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.le.d $[[T0:f[0-9]+]], $f12, $f14
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.le.d $[[T0:f[0-9]+]], $f12, $f13
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp ole double %a, %b
>    %2 = zext i1 %1 to i32
> @@ -510,11 +548,13 @@
>  
>  ; 32-CMP-DAG:    cmp.ueq.d $[[T0:f[0-9]+]], $f12, $f14
>  ; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> -; 32-CMP-DAG:    not $2, $[[T1]]
> +; 32-CMP-DAG:    not $[[T2:[0-9]+]], $[[T1]]
> +; 32-CMP-DAG:    andi $2, $[[T2]], 1
>  
>  ; 64-CMP-DAG:    cmp.ueq.d $[[T0:f[0-9]+]], $f12, $f13
>  ; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> -; 64-CMP-DAG:    not $2, $[[T1]]
> +; 64-CMP-DAG:    not $[[T2:[0-9]+]], $[[T1]]
> +; 64-CMP-DAG:    andi $2, $[[T2]], 1
>  
>    %1 = fcmp one double %a, %b
>    %2 = zext i1 %1 to i32
> @@ -536,11 +576,13 @@
>  
>  ; 32-CMP-DAG:    cmp.un.d $[[T0:f[0-9]+]], $f12, $f14
>  ; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> -; 32-CMP-DAG:    not $2, $[[T1]]
> +; 32-CMP-DAG:    not $[[T2:[0-9]+]], $[[T1]]
> +; 32-CMP-DAG:    andi $2, $[[T2]], 1
>  
>  ; 64-CMP-DAG:    cmp.un.d $[[T0:f[0-9]+]], $f12, $f13
>  ; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> -; 64-CMP-DAG:    not $2, $[[T1]]
> +; 64-CMP-DAG:    not $[[T2:[0-9]+]], $[[T1]]
> +; 64-CMP-DAG:    andi $2, $[[T2]], 1
>  
>    %1 = fcmp ord double %a, %b
>    %2 = zext i1 %1 to i32
> @@ -561,10 +603,12 @@
>  ; 64-C-DAG:      movt $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.ueq.d $[[T0:f[0-9]+]], $f12, $f14
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.ueq.d $[[T0:f[0-9]+]], $f12, $f13
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp ueq double %a, %b
>    %2 = zext i1 %1 to i32
> @@ -585,10 +629,12 @@
>  ; 64-C-DAG:      movf $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.ult.d $[[T0:f[0-9]+]], $f14, $f12
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.ult.d $[[T0:f[0-9]+]], $f13, $f12
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp ugt double %a, %b
>    %2 = zext i1 %1 to i32
> @@ -609,10 +655,12 @@
>  ; 64-C-DAG:      movf $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.ule.d $[[T0:f[0-9]+]], $f14, $f12
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.ule.d $[[T0:f[0-9]+]], $f13, $f12
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp uge double %a, %b
>    %2 = zext i1 %1 to i32
> @@ -633,10 +681,12 @@
>  ; 64-C-DAG:      movt $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.ult.d $[[T0:f[0-9]+]], $f12, $f14
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.ult.d $[[T0:f[0-9]+]], $f12, $f13
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp ult double %a, %b
>    %2 = zext i1 %1 to i32
> @@ -657,10 +707,12 @@
>  ; 64-C-DAG:      movt $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.ule.d $[[T0:f[0-9]+]], $f12, $f14
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.ule.d $[[T0:f[0-9]+]], $f12, $f13
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp ule double %a, %b
>    %2 = zext i1 %1 to i32
> @@ -682,11 +734,13 @@
>  
>  ; 32-CMP-DAG:    cmp.eq.d $[[T0:f[0-9]+]], $f12, $f14
>  ; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> -; 32-CMP-DAG:    not $2, $[[T1]]
> +; 32-CMP-DAG:    not $[[T2:[0-9]+]], $[[T1]]
> +; 32-CMP-DAG:    andi $2, $[[T2]], 1
>  
>  ; 64-CMP-DAG:    cmp.eq.d $[[T0:f[0-9]+]], $f12, $f13
>  ; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> -; 64-CMP-DAG:    not $2, $[[T1]]
> +; 64-CMP-DAG:    not $[[T2:[0-9]+]], $[[T1]]
> +; 64-CMP-DAG:    andi $2, $[[T2]], 1
>  
>    %1 = fcmp une double %a, %b
>    %2 = zext i1 %1 to i32
> @@ -707,10 +761,12 @@
>  ; 64-C-DAG:      movt $[[T0]], $1, $fcc0
>  
>  ; 32-CMP-DAG:    cmp.un.d $[[T0:f[0-9]+]], $f12, $f14
> -; 32-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 32-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 32-CMP-DAG:    andi $2, $[[T1]], 1
>  
>  ; 64-CMP-DAG:    cmp.un.d $[[T0:f[0-9]+]], $f12, $f13
> -; 64-CMP-DAG:    mfc1 $2, $[[T0]]
> +; 64-CMP-DAG:    mfc1 $[[T1:[0-9]+]], $[[T0]]
> +; 64-CMP-DAG:    andi $2, $[[T1]], 1
>  
>    %1 = fcmp uno double %a, %b
>    %2 = zext i1 %1 to i32
> Index: test/CodeGen/Mips/select.ll
> ===================================================================
> --- test/CodeGen/Mips/select.ll
> +++ test/CodeGen/Mips/select.ll
> @@ -516,9 +516,8 @@
>  ; 32R6-DAG:      mtc1 $7, $[[F3:f[0-9]+]]
>  ; 32R6:          cmp.eq.s $[[CC:f[0-9]+]], $[[F2]], $[[F3]]
>  ; 32R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
> +; 32R6:          andi $[[CCGPR]], $[[CCGPR]], 1
>  ; 32R6:          seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]]
> -; FIXME: This move is redundant
> -; 32R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
>  ; 32R6:          selnez $[[NE:[0-9]+]], $4, $[[CCGPR]]
>  ; 32R6:          or $2, $[[NE]], $[[EQ]]
>  
> @@ -532,9 +531,8 @@
>  
>  ; 64R6:          cmp.eq.s $[[CC:f[0-9]+]], $f14, $f15
>  ; 64R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
> +; 64R6:          andi $[[CCGPR]], $[[CCGPR]], 1
>  ; 64R6:          seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]]
> -; FIXME: This move is redundant
> -; 64R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
>  ; 64R6:          selnez $[[NE:[0-9]+]], $4, $[[CCGPR]]
>  ; 64R6:          or $2, $[[NE]], $[[EQ]]
>  
> @@ -563,9 +561,8 @@
>  ; 32R6-DAG:      mtc1 $7, $[[F3:f[0-9]+]]
>  ; 32R6:          cmp.lt.s $[[CC:f[0-9]+]], $[[F2]], $[[F3]]
>  ; 32R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
> +; 32R6:          andi $[[CCGPR]], $[[CCGPR]], 1
>  ; 32R6:          seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]]
> -; FIXME: This move is redundant
> -; 32R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
>  ; 32R6:          selnez $[[NE:[0-9]+]], $4, $[[CCGPR]]
>  ; 32R6:          or $2, $[[NE]], $[[EQ]]
>  
> @@ -579,9 +576,8 @@
>  
>  ; 64R6:          cmp.lt.s $[[CC:f[0-9]+]], $f14, $f15
>  ; 64R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
> +; 64R6:          andi $[[CCGPR]], $[[CCGPR]], 1
>  ; 64R6:          seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]]
> -; FIXME: This move is redundant
> -; 64R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
>  ; 64R6:          selnez $[[NE:[0-9]+]], $4, $[[CCGPR]]
>  ; 64R6:          or $2, $[[NE]], $[[EQ]]
>    %cmp = fcmp olt float %f2, %f3
> @@ -609,9 +605,8 @@
>  ; 32R6-DAG:      mtc1 $7, $[[F3:f[0-9]+]]
>  ; 32R6:          cmp.lt.s $[[CC:f[0-9]+]], $[[F3]], $[[F2]]
>  ; 32R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
> +; 32R6:          andi $[[CCGPR]], $[[CCGPR]], 1
>  ; 32R6:          seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]]
> -; FIXME: This move is redundant
> -; 32R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
>  ; 32R6:          selnez $[[NE:[0-9]+]], $4, $[[CCGPR]]
>  ; 32R6:          or $2, $[[NE]], $[[EQ]]
>  
> @@ -625,9 +620,8 @@
>  
>  ; 64R6:          cmp.lt.s $[[CC:f[0-9]+]], $f15, $f14
>  ; 64R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
> +; 64R6:          andi $[[CCGPR]], $[[CCGPR]], 1
>  ; 64R6:          seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]]
> -; FIXME: This move is redundant
> -; 64R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
>  ; 64R6:          selnez $[[NE:[0-9]+]], $4, $[[CCGPR]]
>  ; 64R6:          or $2, $[[NE]], $[[EQ]]
>  
> @@ -668,9 +662,8 @@
>  ; 32R6-DAG:      ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]])
>  ; 32R6:          cmp.eq.d $[[CC:f[0-9]+]], $[[TMP]], $[[TMP1]]
>  ; 32R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
> +; 32R6:          andi $[[CCGPR]], $[[CCGPR]], 1
>  ; 32R6:          seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]]
> -; FIXME: This move is redundant
> -; 32R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
>  ; 32R6:          selnez $[[NE:[0-9]+]], $4, $[[CCGPR]]
>  ; 32R6:          or $2, $[[NE]], $[[EQ]]
>  
> @@ -702,9 +695,8 @@
>  ; 64R6-DAG:      ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]])
>  ; 64R6:          cmp.eq.d $[[CC:f[0-9]+]], $[[TMP]], $[[TMP1]]
>  ; 64R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
> +; 64R6:          andi $[[CCGPR]], $[[CCGPR]], 1
>  ; 64R6:          seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]]
> -; FIXME: This move is redundant
> -; 64R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
>  ; 64R6:          selnez $[[NE:[0-9]+]], $4, $[[CCGPR]]
>  ; 64R6:          or $2, $[[NE]], $[[EQ]]
>  
> @@ -747,9 +739,8 @@
>  ; 32R6-DAG:      ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]])
>  ; 32R6:          cmp.lt.d $[[CC:f[0-9]+]], $[[TMP]], $[[TMP1]]
>  ; 32R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
> +; 32R6:          andi $[[CCGPR]], $[[CCGPR]], 1
>  ; 32R6:          seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]]
> -; FIXME: This move is redundant
> -; 32R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
>  ; 32R6:          selnez $[[NE:[0-9]+]], $4, $[[CCGPR]]
>  ; 32R6:          or $2, $[[NE]], $[[EQ]]
>  
> @@ -781,9 +772,8 @@
>  ; 64R6-DAG:      ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]])
>  ; 64R6:          cmp.lt.d $[[CC:f[0-9]+]], $[[TMP]], $[[TMP1]]
>  ; 64R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
> +; 64R6:          andi $[[CCGPR]], $[[CCGPR]], 1
>  ; 64R6:          seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]]
> -; FIXME: This move is redundant
> -; 64R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
>  ; 64R6:          selnez $[[NE:[0-9]+]], $4, $[[CCGPR]]
>  ; 64R6:          or $2, $[[NE]], $[[EQ]]
>  
> @@ -826,9 +816,8 @@
>  ; 32R6-DAG:      ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]])
>  ; 32R6:          cmp.lt.d $[[CC:f[0-9]+]], $[[TMP1]], $[[TMP]]
>  ; 32R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
> +; 32R6:          andi $[[CCGPR]], $[[CCGPR]], 1
>  ; 32R6:          seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]]
> -; FIXME: This move is redundant
> -; 32R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
>  ; 32R6:          selnez $[[NE:[0-9]+]], $4, $[[CCGPR]]
>  ; 32R6:          or $2, $[[NE]], $[[EQ]]
>  
> @@ -860,9 +849,8 @@
>  ; 64R6-DAG:      ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]])
>  ; 64R6:          cmp.lt.d $[[CC:f[0-9]+]], $[[TMP1]], $[[TMP]]
>  ; 64R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
> +; 64R6:          andi $[[CCGPR]], $[[CCGPR]], 1
>  ; 64R6:          seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]]
> -; FIXME: This move is redundant
> -; 64R6:          mfc1 $[[CCGPR:[0-9]+]], $[[CC]]
>  ; 64R6:          selnez $[[NE:[0-9]+]], $4, $[[CCGPR]]
>  ; 64R6:          or $2, $[[NE]], $[[EQ]]
>  

> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list