llvm.org GIT mirror llvm / c4dd3c3
Add mod, copysign, abs operations to APFloat. Implement some constant folding in SelectionDAG and DAGCombiner using APFloat. Remove double versions of constructor and getValue from ConstantFPSDNode. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41664 91177308-0d34-0410-b5e6-96231b3b80d8 Dale Johannesen 13 years ago
4 changed file(s) with 78 addition(s) and 51 deletion(s). Raw diff Collapse all Expand all
9494
9595 // APInt contains static functions implementing bignum arithmetic.
9696 #include "llvm/ADT/APInt.h"
97 #include "llvm/CodeGen/ValueTypes.h"
9798
9899 namespace llvm {
99100
176177 opStatus subtract(const APFloat &, roundingMode);
177178 opStatus multiply(const APFloat &, roundingMode);
178179 opStatus divide(const APFloat &, roundingMode);
180 opStatus mod(const APFloat &, roundingMode);
181 void copySign(const APFloat &);
179182 opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode);
180 void changeSign();
183 void changeSign(); // neg
184 void clearSign(); // abs
181185
182186 /* Conversions. */
183187 opStatus convert(const fltSemantics &, roundingMode);
11461146 class ConstantFPSDNode : public SDNode {
11471147 APFloat Value;
11481148 virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
1149 // Longterm plan: replace all uses of getValue with getValueAPF, remove
1150 // getValue, rename getValueAPF to getValue.
11491151 protected:
11501152 friend class SelectionDAG;
1151 ConstantFPSDNode(bool isTarget, double val, MVT::ValueType VT)
1152 : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP,
1153 getSDVTList(VT)),
1154 Value(VT==MVT::f64 ? APFloat(val) : APFloat((float)val)) {
1155 }
11561153 ConstantFPSDNode(bool isTarget, const APFloat& val, MVT::ValueType VT)
11571154 : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP,
11581155 getSDVTList(VT)), Value(val) {
11591156 }
11601157 public:
11611158
1162 // Longterm plan: replace all uses of getValue with getValueAPF, remove
1163 // getValue, rename getValueAPF to getValue.
1164 double getValue() const {
1165 if ( getValueType(0)==MVT::f64)
1166 return Value.convertToDouble();
1167 else
1168 return Value.convertToFloat();
1169 }
11701159 const APFloat& getValueAPF() const { return Value; }
11711160
11721161 /// isExactlyValue - We don't rely on operator== working on double values, as
11731162 /// it returns true for things that are clearly not equal, like -0.0 and 0.0.
11741163 /// As such, this method can be used to do an exact bit-for-bit comparison of
11751164 /// two floating point values.
1165
1166 /// We leave the version with the double argument here because it's just so
1167 /// convenient to write "2.0" and the like. Without this function we'd
1168 /// have to duplicate its logic everywhere it's called.
11761169 bool isExactlyValue(double V) const {
11771170 if (getValueType(0)==MVT::f64)
11781171 return isExactlyValue(APFloat(V));
409409 assert(Depth <= 6 && "GetNegatedExpression doesn't match isNegatibleForFree");
410410 switch (Op.getOpcode()) {
411411 default: assert(0 && "Unknown code");
412 case ISD::ConstantFP:
413 return DAG.getConstantFP(-cast(Op)->getValue(),
414 Op.getValueType());
412 case ISD::ConstantFP: {
413 APFloat V = cast(Op)->getValueAPF();
414 V.changeSign();
415 return DAG.getConstantFP(V, Op.getValueType());
416 }
415417 case ISD::FADD:
416418 // FIXME: determine better conditions for this xform.
417419 assert(UnsafeFPMath);
431433
432434 // -(0-B) -> B
433435 if (ConstantFPSDNode *N0CFP = dyn_cast(Op.getOperand(0)))
434 if (N0CFP->getValue() == 0.0)
436 if (N0CFP->getValueAPF().isZero())
435437 return Op.getOperand(1);
436438
437439 // -(A-B) -> B-A
30793081 if (N0CFP && N1CFP)
30803082 return DAG.getNode(ISD::FSUB, VT, N0, N1);
30813083 // fold (0-B) -> -B
3082 if (UnsafeFPMath && N0CFP && N0CFP->getValue() == 0.0) {
3084 if (UnsafeFPMath && N0CFP && N0CFP->getValueAPF().isZero()) {
30833085 if (isNegatibleForFree(N1))
30843086 return GetNegatedExpression(N1, DAG);
30853087 return DAG.getNode(ISD::FNEG, VT, N1);
33033305
33043306 // fold (fp_round_inreg c1fp) -> c1fp
33053307 if (N0CFP) {
3306 SDOperand Round = DAG.getConstantFP(N0CFP->getValue(), EVT);
3308 SDOperand Round = DAG.getConstantFP(N0CFP->getValueAPF(), EVT);
33073309 return DAG.getNode(ISD::FP_EXTEND, VT, Round);
33083310 }
33093311 return SDOperand();
42064208 if ((RHSOp.getOpcode() == ISD::Constant &&
42074209 cast(RHSOp.Val)->isNullValue()) ||
42084210 (RHSOp.getOpcode() == ISD::ConstantFP &&
4209 !cast(RHSOp.Val)->getValue()))
4211 cast(RHSOp.Val)->getValueAPF().isZero()))
42104212 break;
42114213 }
42124214 Ops.push_back(DAG.getNode(N->getOpcode(), EltType, LHSOp, RHSOp));
726726 if (!MVT::isVector(VT))
727727 return SDOperand(N, 0);
728728 if (!N) {
729 N = new ConstantFPSDNode(isTarget, Val, EltVT);
729 N = new ConstantFPSDNode(isTarget,
730 isDouble ? APFloat(Val) : APFloat((float)Val), EltVT);
730731 CSEMap.InsertNode(N, IP);
731732 AllNodes.push_back(N);
732733 }
16641665 }
16651666 }
16661667
1667 // Constant fold unary operations with an floating point constant operand.
1668 if (ConstantFPSDNode *C = dyn_cast(Operand.Val))
1668 // Constant fold unary operations with a floating point constant operand.
1669 if (ConstantFPSDNode *C = dyn_cast(Operand.Val)) {
1670 APFloat V = C->getValueAPF(); // make copy
16691671 switch (Opcode) {
16701672 case ISD::FNEG:
1671 return getConstantFP(-C->getValue(), VT);
1673 V.changeSign();
1674 return getConstantFP(V, VT);
16721675 case ISD::FABS:
1673 return getConstantFP(fabs(C->getValue()), VT);
1676 V.clearSign();
1677 return getConstantFP(V, VT);
16741678 case ISD::FP_ROUND:
16751679 case ISD::FP_EXTEND:
1676 return getConstantFP(C->getValue(), VT);
1680 // This can return overflow, underflow, or inexact; we don't care.
1681 // FIXME need to be more flexible about rounding mode.
1682 (void) V.convert(VT==MVT::f32 ? APFloat::IEEEsingle :
1683 APFloat::IEEEdouble,
1684 APFloat::rmNearestTiesToEven);
1685 return getConstantFP(V, VT);
16771686 case ISD::FP_TO_SINT:
1678 return getConstant((int64_t)C->getValue(), VT);
1679 case ISD::FP_TO_UINT:
1680 return getConstant((uint64_t)C->getValue(), VT);
1687 case ISD::FP_TO_UINT: {
1688 integerPart x;
1689 assert(integerPartWidth >= 64);
1690 // FIXME need to be more flexible about rounding mode.
1691 APFloat::opStatus s = V.convertToInteger(&x, 64U,
1692 Opcode==ISD::FP_TO_SINT,
1693 APFloat::rmTowardZero);
1694 if (s==APFloat::opInvalidOp) // inexact is OK, in fact usual
1695 break;
1696 return getConstant(x, VT);
1697 }
16811698 case ISD::BIT_CONVERT:
16821699 if (VT == MVT::i32 && C->getValueType(0) == MVT::f32)
1683 return getConstant(FloatToBits(C->getValue()), VT);
1700 return getConstant(FloatToBits(V.convertToFloat()), VT);
16841701 else if (VT == MVT::i64 && C->getValueType(0) == MVT::f64)
1685 return getConstant(DoubleToBits(C->getValue()), VT);
1702 return getConstant(DoubleToBits(V.convertToDouble()), VT);
16861703 break;
16871704 }
1705 }
16881706
16891707 unsigned OpOpcode = Operand.Val->getOpcode();
16901708 switch (Opcode) {
19131931 ConstantFPSDNode *N2CFP = dyn_cast(N2.Val);
19141932 if (N1CFP) {
19151933 if (N2CFP) {
1916 double C1 = N1CFP->getValue(), C2 = N2CFP->getValue();
1934 APFloat V1 = N1CFP->getValueAPF(), V2 = N2CFP->getValueAPF();
1935 APFloat::opStatus s;
19171936 switch (Opcode) {
1918 case ISD::FADD: return getConstantFP(C1 + C2, VT);
1919 case ISD::FSUB: return getConstantFP(C1 - C2, VT);
1920 case ISD::FMUL: return getConstantFP(C1 * C2, VT);
1937 case ISD::FADD:
1938 s = V1.add(V2, APFloat::rmNearestTiesToEven);
1939 if (s!=APFloat::opInvalidOp)
1940 return getConstantFP(V1, VT);
1941 break;
1942 case ISD::FSUB:
1943 s = V1.subtract(V2, APFloat::rmNearestTiesToEven);
1944 if (s!=APFloat::opInvalidOp)
1945 return getConstantFP(V1, VT);
1946 break;
1947 case ISD::FMUL:
1948 s = V1.multiply(V2, APFloat::rmNearestTiesToEven);
1949 if (s!=APFloat::opInvalidOp)
1950 return getConstantFP(V1, VT);
1951 break;
19211952 case ISD::FDIV:
1922 if (C2) return getConstantFP(C1 / C2, VT);
1953 s = V1.divide(V2, APFloat::rmNearestTiesToEven);
1954 if (s!=APFloat::opInvalidOp && s!=APFloat::opDivByZero)
1955 return getConstantFP(V1, VT);
19231956 break;
19241957 case ISD::FREM :
1925 if (C2) return getConstantFP(fmod(C1, C2), VT);
1958 s = V1.mod(V2, APFloat::rmNearestTiesToEven);
1959 if (s!=APFloat::opInvalidOp && s!=APFloat::opDivByZero)
1960 return getConstantFP(V1, VT);
19261961 break;
1927 case ISD::FCOPYSIGN: {
1928 union {
1929 double F;
1930 uint64_t I;
1931 } u1;
1932 u1.F = C1;
1933 if (int64_t(DoubleToBits(C2)) < 0) // Sign bit of RHS set?
1934 u1.I |= 1ULL << 63; // Set the sign bit of the LHS.
1935 else
1936 u1.I &= (1ULL << 63)-1; // Clear the sign bit of the LHS.
1937 return getConstantFP(u1.F, VT);
1938 }
1962 case ISD::FCOPYSIGN:
1963 V1.copySign(V2);
1964 return getConstantFP(V1, VT);
19391965 default: break;
19401966 }
19411967 } else { // Cannonicalize constant to RHS if commutative
36873713 if (const ConstantSDNode *CSDN = dyn_cast(this)) {
36883714 cerr << "<" << CSDN->getValue() << ">";
36893715 } else if (const ConstantFPSDNode *CSDN = dyn_cast(this)) {
3690 cerr << "<" << CSDN->getValue() << ">";
3716 cerr << "<" << (&CSDN->getValueAPF().getSemantics()==&APFloat::IEEEsingle ?
3717 CSDN->getValueAPF().convertToFloat() :
3718 CSDN->getValueAPF().convertToDouble()) << ">";
36913719 } else if (const GlobalAddressSDNode *GADN =
36923720 dyn_cast(this)) {
36933721 int offset = GADN->getOffset();