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<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(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.h =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -167,7 +167,7 @@ SDNode *Node, bool isSigned); std::pair 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/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/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(N); if (!CN) { const BuildVectorSDNode *BV = dyn_cast(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(N); if (!CN) { const BuildVectorSDNode *BV = dyn_cast(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]]