Make it possible for ints/floats to return different values from getBooleanContents()
authorDaniel Sanders <daniel.sanders@imgtec.com>
Thu, 10 Jul 2014 10:18:12 +0000 (10:18 +0000)
committerDaniel Sanders <daniel.sanders@imgtec.com>
Thu, 10 Jul 2014 10:18:12 +0000 (10:18 +0000)
Summary:
On MIPS32r6/MIPS64r6, floating point comparisons return 0 or -1 but integer
comparisons return 0 or 1.

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.

Reviewers: hfinkel

Reviewed By: hfinkel

Subscribers: hfinkel, jholewinski, mcrosier, llvm-commits

Differential Revision: http://reviews.llvm.org/D4389

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212697 91177308-0d34-0410-b5e6-96231b3b80d8

15 files changed:
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/Mips/MipsISelLowering.cpp
test/CodeGen/Mips/fcmp.ll
test/CodeGen/Mips/select.ll

index c2ae553c778d48479d995e7f00c1f13939a31769..0a31905a37f2889c8e157e13b7a16315f3f3f9d9 100644 (file)
@@ -570,8 +570,8 @@ public:
 
   /// 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 7caa55d39d69f1a2a34ebb8202533a67078d5e35..5e9978d12e8f8ae4ce37864f79108576541d724b 100644 (file)
@@ -284,8 +284,17 @@ public:
   /// 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;
+  ///
+  /// Some cpus also treat floating point types the same way as they treat
+  /// vectors instead of the way they treat scalars.
+  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.
@@ -950,9 +959,19 @@ public:
   virtual void resetOperationActions() {}
 
 protected:
-  /// 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; }
+  /// Specify how the target extends the result of integer and floating point
+  /// boolean values from i1 to a wider type.  See getBooleanContents.
+  void setBooleanContents(BooleanContent Ty) {
+    BooleanContents = Ty;
+    BooleanFloatContents = Ty;
+  }
+
+  /// Specify how the target extends the result of integer and floating point
+  /// boolean values from i1 to a wider type.  See getBooleanContents.
+  void setBooleanContents(BooleanContent IntTy, BooleanContent FloatTy) {
+    BooleanContents = IntTy;
+    BooleanFloatContents = FloatTy;
+  }
 
   /// Specify how the target extends the result of a vector boolean value from a
   /// vector of i1 to a wider type.  See getBooleanContents.
@@ -1496,6 +1515,10 @@ private:
   /// 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 1df041dcdd0fd67731dd3c3f53859e07e1c07bb4..df273659e49293f71c5d3f74bb66a0b588a485f4 100644 (file)
@@ -3958,14 +3958,14 @@ SDValue DAGCombiner::visitSHL(SDNode *N) {
     // 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);
@@ -4524,11 +4524,20 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
   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. This is because we can't tell whether we
+  // have an integer-based boolean or a floating-point-based boolean unless we
+  // can find the SETCC that produced it and inspect its operands. This is
+  // fairly easy if C is the SETCC node, but it can potentially be
+  // undiscoverable (or not reasonably discoverable). For example, it could be
+  // in another basic block or it could require searching a complicated
+  // expression.
   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)
@@ -5077,12 +5086,12 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
   }
 
   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.
@@ -11243,8 +11252,8 @@ SDValue DAGCombiner::SimplifySelectCC(SDLoc DL, SDValue N0, SDValue N1,
 
   // 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 b200adcae80fe6a3bb73952be2ad1a4d7c618f47..c0e8c8c2b05be4690670e6385f8f2070c7d1891f 100644 (file)
@@ -3761,7 +3761,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     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 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
       = 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 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     // 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 d803976721c57a69bbf351e7fde38e70694dd50b..6feac0de73f4a06e6b113167d8158f7fd7e06a96 100644 (file)
@@ -519,7 +519,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_VSELECT(SDNode *N) {
   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 @@ SDValue DAGTypeLegalizer::PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo) {
   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 @@ SDValue DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) {
   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 87ffa6a9406b0cfeb72147ad83ce3323258b201e..bd7dacf2bc6945aeb56f9ee2c4057c18cfb6385e 100644 (file)
@@ -1065,11 +1065,14 @@ DAGTypeLegalizer::ExpandChainLibCall(RTLIB::Libcall LC,
 /// 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 a6bbc218dd22b567b6baf62249fd3e782a86fad1..e52fb3c05e39c912fb5e4d78a851a08b97c3bf8e 100644 (file)
@@ -167,7 +167,7 @@ private:
                                                  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 3fa64843a93a0c019c514c0d01e9a4f3564cafb1..25dc98e0eb9b15e3f58d0047944e46cae09ff0bc 100644 (file)
@@ -793,9 +793,9 @@ SDValue VectorLegalizer::ExpandVSELECT(SDValue Op) {
   // 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 c50625e208052846c9f065ed729ed39c23ca1bcc..415d4e3f5073b05e39ad470e28934c547da42a07 100644 (file)
@@ -257,8 +257,26 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N) {
 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. There is a full explanation for this in
+  // DAGCombiner::visitSELECT() where the same issue affects folding
+  // (select C, 0, 1) to (xor C, 1).
+  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 +375,7 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_VSETCC(SDNode *N) {
   // 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 119b0255e7c36d86cb713b40389203138ddc8826..6a3fa7aef1fc1d50f02b93eca3fb16c327b8ce37 100644 (file)
@@ -1012,11 +1012,12 @@ SDValue SelectionDAG::getZExtOrTrunc(SDValue Op, SDLoc DL, EVT VT) {
     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);
 }
 
@@ -1054,7 +1055,7 @@ SDValue SelectionDAG::getNOT(SDLoc DL, SDValue Val, EVT VT) {
 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);
@@ -1776,7 +1777,8 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1,
   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);
   }
@@ -2007,11 +2009,20 @@ void SelectionDAG::computeKnownBits(SDValue Op, APInt &KnownZero,
   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:
@@ -2410,9 +2421,16 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{
     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 578821a19f5cc06fde7274d3d5c5c4e38e33058c..42372a21ed7a8c36025b76efa6fdbd79671a54f5 100644 (file)
@@ -1150,14 +1150,12 @@ bool TargetLowering::isConstTrueVal(const SDNode *N) const {
   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;
     BitVector UndefElements;
     CN = BV->getConstantSplatNode(&UndefElements);
     // Only interested in constant splats, and we don't try to handle undef
@@ -1166,7 +1164,7 @@ bool TargetLowering::isConstTrueVal(const SDNode *N) const {
       return false;
   }
 
-  switch (getBooleanContents(IsVec)) {
+  switch (getBooleanContents(N->getValueType(0))) {
   case UndefinedBooleanContent:
     return CN->getAPIntValue()[0];
   case ZeroOrOneBooleanContent:
@@ -1182,14 +1180,12 @@ bool TargetLowering::isConstFalseVal(const SDNode *N) const {
   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;
     BitVector UndefElements;
     CN = BV->getConstantSplatNode(&UndefElements);
     // Only interested in constant splats, and we don't try to handle undef
@@ -1198,7 +1194,7 @@ bool TargetLowering::isConstFalseVal(const SDNode *N) const {
       return false;
   }
 
-  if (getBooleanContents(IsVec) == UndefinedBooleanContent)
+  if (getBooleanContents(N->getValueType(0)) == UndefinedBooleanContent)
     return !CN->getAPIntValue()[0];
 
   return CN->isNullValue();
@@ -1219,7 +1215,8 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
   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);
   }
@@ -1426,7 +1423,7 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
 
           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;
       }
@@ -1510,7 +1507,8 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
         }
       } 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);
@@ -1781,7 +1779,7 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
     // 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 71c609441bb6b9c4fd36faaebbe9ac98b7563b64..afa58e780ffeee936fd6a7461b921a10f2f83c30 100644 (file)
@@ -690,6 +690,7 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm,
   ExceptionPointerRegister = 0;
   ExceptionSelectorRegister = 0;
   BooleanContents = UndefinedBooleanContent;
+  BooleanFloatContents = UndefinedBooleanContent;
   BooleanVectorContents = UndefinedBooleanContent;
   SchedPreferenceInfo = Sched::ILP;
   JumpBufSize = 0;
index edbba2b089c209f14cf797a3f7dcc140d1b259e1..b7af2d4aaf48240f8fe673a043c99cb841d25406 100644 (file)
@@ -215,6 +215,11 @@ MipsTargetLowering::MipsTargetLowering(MipsTargetMachine &TM)
   // setcc operations results (slt, sgt, ...).
   setBooleanContents(ZeroOrOneBooleanContent);
   setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
+  // The cmp.cond.fmt instruction in MIPS32r6/MIPS64r6 uses 0 and -1 like MSA
+  // does. Integer booleans still use 0 and 1.
+  if (Subtarget->hasMips32r6())
+    setBooleanContents(ZeroOrOneBooleanContent,
+                       ZeroOrNegativeOneBooleanContent);
 
   // Load extented operations for i1 types must be promoted
   setLoadExtAction(ISD::EXTLOAD,  MVT::i1,  Promote);
index dce8a7d6da58027d80e4b830855999979f22b255..b7759831c5a2bffb5cfad17e6a2d892756cbf5f8 100644 (file)
@@ -29,10 +29,12 @@ define i32 @oeq_f32(float %a, float %b) nounwind {
 ; 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 @@ define i32 @ogt_f32(float %a, float %b) nounwind {
 ; 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 @@ define i32 @oge_f32(float %a, float %b) nounwind {
 ; 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 @@ define i32 @olt_f32(float %a, float %b) nounwind {
 ; 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 @@ define i32 @ole_f32(float %a, float %b) nounwind {
 ; 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 @@ define i32 @one_f32(float %a, float %b) nounwind {
 
 ; 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 @@ define i32 @ord_f32(float %a, float %b) nounwind {
 
 ; 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 @@ define i32 @ueq_f32(float %a, float %b) nounwind {
 ; 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 @@ define i32 @ugt_f32(float %a, float %b) nounwind {
 ; 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 @@ define i32 @uge_f32(float %a, float %b) nounwind {
 ; 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 @@ define i32 @ult_f32(float %a, float %b) nounwind {
 ; 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 @@ define i32 @ule_f32(float %a, float %b) nounwind {
 ; 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 @@ define i32 @une_f32(float %a, float %b) nounwind {
 
 ; 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 @@ define i32 @uno_f32(float %a, float %b) nounwind {
 ; 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 @@ define i32 @oeq_f64(double %a, double %b) nounwind {
 ; 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 @@ define i32 @ogt_f64(double %a, double %b) nounwind {
 ; 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 @@ define i32 @oge_f64(double %a, double %b) nounwind {
 ; 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 @@ define i32 @olt_f64(double %a, double %b) nounwind {
 ; 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 @@ define i32 @ole_f64(double %a, double %b) nounwind {
 ; 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 @@ define i32 @one_f64(double %a, double %b) nounwind {
 
 ; 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 @@ define i32 @ord_f64(double %a, double %b) nounwind {
 
 ; 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 @@ define i32 @ueq_f64(double %a, double %b) nounwind {
 ; 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 @@ define i32 @ugt_f64(double %a, double %b) nounwind {
 ; 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 @@ define i32 @uge_f64(double %a, double %b) nounwind {
 ; 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 @@ define i32 @ult_f64(double %a, double %b) nounwind {
 ; 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 @@ define i32 @ule_f64(double %a, double %b) nounwind {
 ; 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 @@ define i32 @une_f64(double %a, double %b) nounwind {
 
 ; 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 @@ define i32 @uno_f64(double %a, double %b) nounwind {
 ; 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 91471a2ce6bb73726ce3aa35934a4eec57c11959..eb2198b36dff34c123fad3e2e0f05ca6d741ee2e 100644 (file)
@@ -516,9 +516,8 @@ entry:
 ; 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 @@ entry:
 
 ; 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 @@ entry:
 ; 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 @@ entry:
 
 ; 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 @@ entry:
 ; 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 @@ entry:
 
 ; 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 @@ entry:
 ; 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 @@ entry:
 ; 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 @@ entry:
 ; 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 @@ entry:
 ; 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 @@ entry:
 ; 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 @@ entry:
 ; 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]]