diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 9068d780996..acee9841585 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -1151,17 +1151,36 @@ protected: friend class SelectionDAG; ConstantFPSDNode(bool isTarget, double val, MVT::ValueType VT) : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, - getSDVTList(VT)), Value(APFloat(val)) { + getSDVTList(VT)), + Value(VT==MVT::f64 ? APFloat(val) : APFloat((float)val)) { + } + ConstantFPSDNode(bool isTarget, APFloat val, MVT::ValueType VT) + : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, + getSDVTList(VT)), Value(val) { } public: - double getValue() const { return Value.convertToDouble(); } + // Longterm plan: replace all uses of getValue with getValueAPF, remove + // getValue, rename getValueAPF to getValue. + double getValue() const { + if ( getValueType(0)==MVT::f64) + return Value.convertToDouble(); + else + return Value.convertToFloat(); + } + APFloat getValueAPF() const { return Value; } /// isExactlyValue - We don't rely on operator== working on double values, as /// it returns true for things that are clearly not equal, like -0.0 and 0.0. /// As such, this method can be used to do an exact bit-for-bit comparison of /// two floating point values. - bool isExactlyValue(double V) const; + bool isExactlyValue(double V) const { + if (getValueType(0)==MVT::f64) + return isExactlyValue(APFloat(V)); + else + return isExactlyValue(APFloat((float)V)); + } + bool isExactlyValue(APFloat V) const; static bool classof(const ConstantFPSDNode *) { return true; } static bool classof(const SDNode *N) { diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d9c09e163b2..2b119a095aa 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3195,14 +3195,10 @@ SDOperand DAGCombiner::visitFCOPYSIGN(SDNode *N) { return DAG.getNode(ISD::FCOPYSIGN, VT, N0, N1); if (N1CFP) { + APFloat V = N1CFP->getValueAPF(); // copysign(x, c1) -> fabs(x) iff ispos(c1) // copysign(x, c1) -> fneg(fabs(x)) iff isneg(c1) - union { - double d; - int64_t i; - } u; - u.d = N1CFP->getValue(); - if (u.i >= 0) + if (!V.isNegative()) return DAG.getNode(ISD::FABS, VT, N0); else return DAG.getNode(ISD::FNEG, VT, DAG.getNode(ISD::FABS, VT, N0)); @@ -3792,7 +3788,7 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) { default: assert(0 && "Unknown FP type"); case MVT::f32: if (!AfterLegalize || TLI.isTypeLegal(MVT::i32)) { - Tmp = DAG.getConstant(FloatToBits(CFP->getValue()), MVT::i32); + Tmp = DAG.getConstant(FloatToBits(CFP->getValueAPF().convertToFloat()), MVT::i32); return DAG.getStore(Chain, Tmp, Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->isVolatile(), ST->getAlignment()); @@ -3800,7 +3796,7 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) { break; case MVT::f64: if (!AfterLegalize || TLI.isTypeLegal(MVT::i64)) { - Tmp = DAG.getConstant(DoubleToBits(CFP->getValue()), MVT::i64); + Tmp = DAG.getConstant(DoubleToBits(CFP->getValueAPF().convertToDouble()), MVT::i64); return DAG.getStore(Chain, Tmp, Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->isVolatile(), ST->getAlignment()); @@ -3808,7 +3804,7 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) { // Many FP stores are not make apparent until after legalize, e.g. for // argument passing. Since this is so common, custom legalize the // 64-bit integer store into two 32-bit stores. - uint64_t Val = DoubleToBits(CFP->getValue()); + uint64_t Val = DoubleToBits(CFP->getValueAPF().convertToDouble()); SDOperand Lo = DAG.getConstant(Val & 0xFFFFFFFF, MVT::i32); SDOperand Hi = DAG.getConstant(Val >> 32, MVT::i32); if (!TLI.isLittleEndian()) std::swap(Lo, Hi); @@ -4365,7 +4361,7 @@ SDOperand DAGCombiner::SimplifySelectCC(SDOperand N0, SDOperand N1, // Check to see if we can simplify the select into an fabs node if (ConstantFPSDNode *CFP = dyn_cast(N1)) { // Allow either -0.0 or 0.0 - if (CFP->getValue() == 0.0) { + if (CFP->getValueAPF().isZero()) { // select (setg[te] X, +/-0.0), X, fneg(X) -> fabs if ((CC == ISD::SETGE || CC == ISD::SETGT) && N0 == N2 && N3.getOpcode() == ISD::FNEG && diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 6155ee160c2..4bd07b60b7f 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -48,8 +48,8 @@ static SDVTList makeVTList(const MVT::ValueType *VTs, unsigned NumVTs) { /// it returns true for things that are clearly not equal, like -0.0 and 0.0. /// As such, this method can be used to do an exact bit-for-bit comparison of /// two floating point values. -bool ConstantFPSDNode::isExactlyValue(double V) const { - return Value.bitwiseIsEqual(APFloat(V)); +bool ConstantFPSDNode::isExactlyValue(APFloat V) const { + return Value.bitwiseIsEqual(V); } //===----------------------------------------------------------------------===// @@ -669,7 +669,6 @@ SDOperand SelectionDAG::getConstant(uint64_t Val, MVT::ValueType VT, bool isT) { return SDOperand(N, 0); } - SDOperand SelectionDAG::getConstantFP(double Val, MVT::ValueType VT, bool isTarget) { assert(MVT::isFloatingPoint(VT) && "Cannot create integer FP constant!");