Remove the assumption that FP's are either float or
authorDale Johannesen <dalej@apple.com>
Fri, 14 Sep 2007 22:26:36 +0000 (22:26 +0000)
committerDale Johannesen <dalej@apple.com>
Fri, 14 Sep 2007 22:26:36 +0000 (22:26 +0000)
double from some of the many places in the optimizers
it appears, and do something reasonable with x86
long double.
Make APInt::dump() public, remove newline, use it to
dump ConstantSDNode's.
Allow APFloats in FoldingSet.
Expand X86 backend handling of long doubles (conversions
to/from int, mostly).

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

13 files changed:
include/llvm/ADT/APInt.h
include/llvm/ADT/FoldingSet.h
include/llvm/Constants.h
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/Support/APInt.cpp
lib/Support/FoldingSet.cpp
lib/Target/CBackend/CBackend.cpp
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86RegisterInfo.cpp
lib/Transforms/Scalar/InstructionCombining.cpp
lib/VMCore/Constants.cpp

index 9a5643bfc5e1bf4b5b50d59f7a215d4c371550a9..c6055dfc27c59251a90d92a656b42f4e5095c6fe 100644 (file)
@@ -153,11 +153,6 @@ class APInt {
                      const APInt &RHS, uint32_t rhsWords,
                      APInt *Quotient, APInt *Remainder);
 
-#ifndef NDEBUG
-  /// @brief debug method
-  void dump() const;
-#endif
-
 public:
   /// @name Constructors
   /// @{
@@ -1165,6 +1160,11 @@ public:
   static void tcSetLeastSignificantBits(integerPart *, unsigned int,
                                        unsigned int bits);
 
+#ifndef NDEBUG
+  /// @brief debug method
+  void dump() const;
+#endif
+
   /// @}
 };
 
index 155243a6277c6d1ecaba4fe615e32074c43ef459..7fca63867ba65af026886921a8dd819c345828d0 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "llvm/Support/DataTypes.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/APFloat.h"
 #include <string>
 
 namespace llvm {
@@ -153,6 +154,7 @@ public:
     void AddInteger(uint64_t I);
     void AddFloat(float F);
     void AddDouble(double D);
+    void AddAPFloat(const APFloat& apf);
     void AddString(const std::string &String);
     
     /// ComputeHash - Compute a strong hash value for this NodeID, used to 
index b6b3f6346f64ed6c35d4e9c0156ccbb5bce63057..2f3ad9d6ebc054f02612dead7f8fa453ca2a0dc9 100644 (file)
@@ -231,6 +231,9 @@ public:
   /// considers -0.0 to be null as well as 0.0.  :(
   virtual bool isNullValue() const;
 
+  // Get a negative zero.
+  static ConstantFP *getNegativeZero(const Type* Ty);
+
   /// 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
index da55eafdb28a2b72d6e91089680a131e961e50ad..d709169d351f74ee6a2f07848a7bdf2def43378f 100644 (file)
@@ -486,15 +486,23 @@ static SDOperand ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP,
   // double.
   MVT::ValueType VT = CFP->getValueType(0);
   bool isDouble = VT == MVT::f64;
-  ConstantFP *LLVMC = ConstantFP::get(isDouble ? Type::DoubleTy :
-                                      Type::FloatTy, CFP->getValueAPF());
+  ConstantFP *LLVMC = ConstantFP::get(VT==MVT::f64 ? Type::DoubleTy :
+                                      VT==MVT::f32 ? Type::FloatTy :
+                                      VT==MVT::f80 ? Type::X86_FP80Ty :
+                                      VT==MVT::f128 ? Type::FP128Ty :
+                                      VT==MVT::ppcf128 ? Type::PPC_FP128Ty :
+                                      Type::VoidTy,   // error
+                                      CFP->getValueAPF());
   if (!UseCP) {
+    if (VT!=MVT::f64 && VT!=MVT::f32)
+      assert(0 && "Invalid type expansion");
     return DAG.getConstant(LLVMC->getValueAPF().convertToAPInt().getZExtValue(),
                            isDouble ? MVT::i64 : MVT::i32);
   }
 
   if (isDouble && CFP->isValueValidForType(MVT::f32, CFP->getValueAPF()) &&
       // Only do this if the target has a native EXTLOAD instruction from f32.
+      // Do not try to be clever about long doubles (so far)
       TLI.isLoadXLegal(ISD::EXTLOAD, MVT::f32)) {
     LLVMC = cast<ConstantFP>(ConstantExpr::getFPTrunc(LLVMC,Type::FloatTy));
     VT = MVT::f32;
@@ -1976,19 +1984,22 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       // to phase ordering between legalized code and the dag combiner.  This
       // probably means that we need to integrate dag combiner and legalizer
       // together.
-      if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(ST->getValue())) {
+      // We generally can't do this one for long doubles.
+      if (ConstantFPSDNode *CFP =dyn_cast<ConstantFPSDNode>(ST->getValue())) {
         if (CFP->getValueType(0) == MVT::f32) {
           Tmp3 = DAG.getConstant((uint32_t)CFP->getValueAPF().
                                           convertToAPInt().getZExtValue(),
                                   MVT::i32);
-        } else {
-          assert(CFP->getValueType(0) == MVT::f64 && "Unknown FP type!");
+          Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+                                SVOffset, isVolatile, Alignment);
+          break;
+        } else if (CFP->getValueType(0) == MVT::f64) {
           Tmp3 = DAG.getConstant(CFP->getValueAPF().convertToAPInt().
                                    getZExtValue(), MVT::i64);
+          Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+                                SVOffset, isVolatile, Alignment);
+          break;
         }
-        Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
-                              SVOffset, isVolatile, Alignment);
-        break;
       }
       
       switch (getTypeAction(ST->getStoredVT())) {
@@ -4609,12 +4620,16 @@ ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, SDOperand Source) {
     SDOperand FudgeInReg;
     if (DestTy == MVT::f32)
       FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, NULL, 0);
-    else {
-      assert(DestTy == MVT::f64 && "Unexpected conversion");
+    else if (DestTy == MVT::f64)
       // FIXME: Avoid the extend by construction the right constantpool?
       FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(),
                                   CPIdx, NULL, 0, MVT::f32);
-    }
+    else if (DestTy == MVT::f80)
+      FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, MVT::f80, DAG.getEntryNode(),
+                                  CPIdx, NULL, 0, MVT::f32);
+    else 
+      assert(0 && "Unexpected conversion");
+
     MVT::ValueType SCVT = SignedConv.getValueType();
     if (SCVT != DestTy) {
       // Destination type needs to be expanded as well. The FADD now we are
@@ -4722,9 +4737,11 @@ SDOperand SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
     if (DestVT == MVT::f64) {
       // do nothing
       Result = Sub;
-    } else {
+    } else if (DestVT == MVT::f32) {
      // if f32 then cast to f32
       Result = DAG.getNode(ISD::FP_ROUND, MVT::f32, Sub);
+    } else if (DestVT == MVT::f80) {
+      Result = DAG.getNode(ISD::FP_EXTEND, MVT::f80, Sub);
     }
     return Result;
   }
index 0defc12e05e8b23dea6da6d446f61427648e53d8..3744c4ad663a83bf49646933124a23f6e64e5cab 100644 (file)
@@ -322,13 +322,7 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, SDNode *N) {
     break;
   case ISD::TargetConstantFP:
   case ISD::ConstantFP: {
-    APFloat V = cast<ConstantFPSDNode>(N)->getValueAPF();
-    if (&V.getSemantics() == &APFloat::IEEEdouble)
-      ID.AddDouble(V.convertToDouble());
-    else if (&V.getSemantics() == &APFloat::IEEEsingle)
-      ID.AddDouble((double)V.convertToFloat());
-    else
-      assert(0);
+    ID.AddAPFloat(cast<ConstantFPSDNode>(N)->getValueAPF());
     break;
   }
   case ISD::TargetGlobalAddress:
@@ -709,25 +703,21 @@ SDOperand SelectionDAG::getConstantFP(const APFloat& V, MVT::ValueType VT,
                                 
   MVT::ValueType EltVT =
     MVT::isVector(VT) ? MVT::getVectorElementType(VT) : VT;
-  bool isDouble = (EltVT == MVT::f64);
-  double Val = isDouble ? V.convertToDouble() : (double)V.convertToFloat();
 
   // Do the map lookup using the actual bit pattern for the floating point
   // value, so that we don't have problems with 0.0 comparing equal to -0.0, and
   // we don't have issues with SNANs.
   unsigned Opc = isTarget ? ISD::TargetConstantFP : ISD::ConstantFP;
-  // ?? Should we store float/double/longdouble separately in ID?
   FoldingSetNodeID ID;
   AddNodeIDNode(ID, Opc, getVTList(EltVT), 0, 0);
-  ID.AddDouble(Val);
+  ID.AddAPFloat(V);
   void *IP = 0;
   SDNode *N = NULL;
   if ((N = CSEMap.FindNodeOrInsertPos(ID, IP)))
     if (!MVT::isVector(VT))
       return SDOperand(N, 0);
   if (!N) {
-    N = new ConstantFPSDNode(isTarget, 
-      isDouble ? APFloat(Val) : APFloat((float)Val), EltVT);
+    N = new ConstantFPSDNode(isTarget, V, EltVT);
     CSEMap.InsertNode(N, IP);
     AllNodes.push_back(N);
   }
@@ -3724,9 +3714,15 @@ void SDNode::dump(const SelectionDAG *G) const {
   if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(this)) {
     cerr << "<" << CSDN->getValue() << ">";
   } else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(this)) {
-    cerr << "<" << (&CSDN->getValueAPF().getSemantics()==&APFloat::IEEEsingle ? 
-                    CSDN->getValueAPF().convertToFloat() :
-                    CSDN->getValueAPF().convertToDouble()) << ">";
+    if (&CSDN->getValueAPF().getSemantics()==&APFloat::IEEEsingle)
+      cerr << "<" << CSDN->getValueAPF().convertToFloat() << ">";
+    else if (&CSDN->getValueAPF().getSemantics()==&APFloat::IEEEdouble)
+      cerr << "<" << CSDN->getValueAPF().convertToDouble() << ">";
+    else {
+      cerr << "<APFloat(";
+      CSDN->getValueAPF().convertToAPInt().dump();
+      cerr << ")>";
+    }
   } else if (const GlobalAddressSDNode *GADN =
              dyn_cast<GlobalAddressSDNode>(this)) {
     int offset = GADN->getOffset();
index 561b303f7086d0f8503d0e9080f42cb186c57883..14691ee485bbc637508656fc82bff5c3b71933a0 100644 (file)
@@ -2004,8 +2004,7 @@ void SelectionDAGLowering::visitSub(User &I) {
       const Type *ElTy = DestTy->getElementType();
       if (ElTy->isFloatingPoint()) {
         unsigned VL = DestTy->getNumElements();
-        std::vector<Constant*> NZ(VL, ConstantFP::get(ElTy, 
-          ElTy==Type::FloatTy ? APFloat(-0.0f) : APFloat(-0.0)));
+        std::vector<Constant*> NZ(VL, ConstantFP::getNegativeZero(ElTy));
         Constant *CNZ = ConstantVector::get(&NZ[0], NZ.size());
         if (CV == CNZ) {
           SDOperand Op2 = getValue(I.getOperand(1));
@@ -2017,7 +2016,7 @@ void SelectionDAGLowering::visitSub(User &I) {
   }
   if (Ty->isFloatingPoint()) {
     if (ConstantFP *CFP = dyn_cast<ConstantFP>(I.getOperand(0)))
-      if (CFP->isExactlyValue(-0.0)) {
+      if (CFP->isExactlyValue(ConstantFP::getNegativeZero(Ty)->getValueAPF())) {
         SDOperand Op2 = getValue(I.getOperand(1));
         setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2));
         return;
index 277a0b0c113c35b187b971b63b3bec286a2db164..15de08ed055aa092e534edb33ef242be755cc6e7 100644 (file)
@@ -2009,7 +2009,7 @@ void APInt::dump() const
     cerr << pVal[i-1] << " ";
   }
   cerr << " U(" << this->toStringUnsigned(10) << ") S("
-       << this->toStringSigned(10) << ")\n" << std::setbase(10);
+       << this->toStringSigned(10) << ")" << std::setbase(10);
 }
 #endif
 
index 0ccb3a6cc3284d388331c052b3fcedc8a71dc3df..70daad9a619501ca2761596be65a44868c5dbf4b 100644 (file)
@@ -56,6 +56,12 @@ void FoldingSetImpl::NodeID::AddFloat(float F) {
 void FoldingSetImpl::NodeID::AddDouble(double D) {
  AddInteger(DoubleToBits(D));
 }
+void FoldingSetImpl::NodeID::AddAPFloat(const APFloat& apf) {
+  APInt api = apf.convertToAPInt();
+  const uint64_t *p = api.getRawData();
+  for (int i=0; i<api.getNumWords(); i++)
+    AddInteger(*p++);
+}
 void FoldingSetImpl::NodeID::AddString(const std::string &String) {
   unsigned Size = String.size();
   Bits.push_back(Size);
index 9fc30c45da1405e9d9e0e0e5632fa18c3bbd5e5a..5f6d5905bf56ea77eab131e68ac3d3f94fbd62cd 100644 (file)
@@ -604,6 +604,9 @@ void CWriter::printConstantVector(ConstantVector *CP) {
 // only deal in IEEE FP).
 //
 static bool isFPCSafeToPrint(const ConstantFP *CFP) {
+  // Do long doubles the hard way for now.
+  if (CFP->getType()!=Type::FloatTy && CFP->getType()!=Type::DoubleTy)
+    return false;
   APFloat APF = APFloat(CFP->getValueAPF());  // copy
   if (CFP->getType()==Type::FloatTy)
     APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven);
index b073887bd10464e3f137820b5dea09dc2b06d343..55f37a658465f56efd2b861ea27bb305fa9cb1bc 100644 (file)
@@ -99,9 +99,11 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   setOperationAction(ISD::SINT_TO_FP       , MVT::i1   , Promote);
   setOperationAction(ISD::SINT_TO_FP       , MVT::i8   , Promote);
   // SSE has no i16 to fp conversion, only i32
-  if (X86ScalarSSE)
+  if (X86ScalarSSE) {
     setOperationAction(ISD::SINT_TO_FP     , MVT::i16  , Promote);
-  else {
+    // f32 and f64 cases are Legal, f80 case is not
+    setOperationAction(ISD::SINT_TO_FP     , MVT::i32  , Custom);
+  } else {
     setOperationAction(ISD::SINT_TO_FP     , MVT::i16  , Custom);
     setOperationAction(ISD::SINT_TO_FP     , MVT::i32  , Custom);
   }
@@ -119,6 +121,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
 
   if (X86ScalarSSE) {
     setOperationAction(ISD::FP_TO_SINT     , MVT::i16  , Promote);
+    // f32 and f64 cases are Legal, f80 case is not
+    setOperationAction(ISD::FP_TO_SINT     , MVT::i32  , Custom);
   } else {
     setOperationAction(ISD::FP_TO_SINT     , MVT::i16  , Custom);
     setOperationAction(ISD::FP_TO_SINT     , MVT::i32  , Custom);
@@ -189,11 +193,13 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   setOperationAction(ISD::SELECT          , MVT::i32  , Custom);
   setOperationAction(ISD::SELECT          , MVT::f32  , Custom);
   setOperationAction(ISD::SELECT          , MVT::f64  , Custom);
+  setOperationAction(ISD::SELECT          , MVT::f80  , Custom);
   setOperationAction(ISD::SETCC           , MVT::i8   , Custom);
   setOperationAction(ISD::SETCC           , MVT::i16  , Custom);
   setOperationAction(ISD::SETCC           , MVT::i32  , Custom);
   setOperationAction(ISD::SETCC           , MVT::f32  , Custom);
   setOperationAction(ISD::SETCC           , MVT::f64  , Custom);
+  setOperationAction(ISD::SETCC           , MVT::f80  , Custom);
   if (Subtarget->is64Bit()) {
     setOperationAction(ISD::SELECT        , MVT::i64  , Custom);
     setOperationAction(ISD::SETCC         , MVT::i64  , Custom);
@@ -334,6 +340,9 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
 
   // Long double always uses X87.
   addRegisterClass(MVT::f80, X86::RFP80RegisterClass);
+  setOperationAction(ISD::UNDEF,     MVT::f80, Expand);
+  setOperationAction(ISD::FCOPYSIGN, MVT::f80, Expand);
+  setOperationAction(ISD::ConstantFP, MVT::f80, Expand);
 
   // First set operation action for all vector types to expand. Then we
   // will selectively turn on ones that can be effectively codegen'd.
@@ -3326,9 +3335,14 @@ SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
   SDOperand Chain = DAG.getStore(DAG.getEntryNode(), Op.getOperand(0),
                                  StackSlot, NULL, 0);
 
+  // These are really Legal; caller falls through into that case.
+  if (SrcVT==MVT::i32 && Op.getValueType() != MVT::f80 && X86ScalarSSE)
+    return Result;
+
   // Build the FILD
   SDVTList Tys;
-  if (X86ScalarSSE)
+  bool useSSE = X86ScalarSSE && Op.getValueType() != MVT::f80;
+  if (useSSE)
     Tys = DAG.getVTList(MVT::f64, MVT::Other, MVT::Flag);
   else
     Tys = DAG.getVTList(Op.getValueType(), MVT::Other);
@@ -3336,10 +3350,10 @@ SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
   Ops.push_back(Chain);
   Ops.push_back(StackSlot);
   Ops.push_back(DAG.getValueType(SrcVT));
-  Result = DAG.getNode(X86ScalarSSE ? X86ISD::FILD_FLAG :X86ISD::FILD,
+  Result = DAG.getNode(useSSE ? X86ISD::FILD_FLAG :X86ISD::FILD,
                        Tys, &Ops[0], Ops.size());
 
-  if (X86ScalarSSE) {
+  if (useSSE) {
     Chain = Result.getValue(1);
     SDOperand InFlag = Result.getValue(2);
 
@@ -3368,11 +3382,17 @@ SDOperand X86TargetLowering::LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG) {
          "Unknown FP_TO_SINT to lower!");
   // We lower FP->sint64 into FISTP64, followed by a load, all to a temporary
   // stack slot.
+  SDOperand Result;
   MachineFunction &MF = DAG.getMachineFunction();
   unsigned MemSize = MVT::getSizeInBits(Op.getValueType())/8;
   int SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize);
   SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
 
+  // These are really Legal.
+  if (Op.getValueType() == MVT::i32 && X86ScalarSSE && 
+      Op.getOperand(0).getValueType() != MVT::f80)
+    return Result;
+
   unsigned Opc;
   switch (Op.getValueType()) {
     default: assert(0 && "Invalid FP_TO_SINT to lower!");
@@ -3383,7 +3403,7 @@ SDOperand X86TargetLowering::LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG) {
 
   SDOperand Chain = DAG.getEntryNode();
   SDOperand Value = Op.getOperand(0);
-  if (X86ScalarSSE) {
+  if (X86ScalarSSE && Op.getOperand(0).getValueType() != MVT::f80) {
     assert(Op.getValueType() == MVT::i64 && "Invalid FP_TO_SINT to lower!");
     Chain = DAG.getStore(Chain, Value, StackSlot, NULL, 0);
     SDVTList Tys = DAG.getVTList(Op.getOperand(0).getValueType(), MVT::Other);
index 557f07e8b404fe1003578618ef251c4c028a1151..4a8c275bc54efba68ded5becf3058540c091469d 100644 (file)
@@ -168,7 +168,11 @@ void X86RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
     Opc = X86::MOV32_mr;
   } else if (RC == &X86::GR16_RegClass) {
     Opc = X86::MOV16_mr;
+  } else if (RC == &X86::RFP80RegClass) {
+    Opc = X86::ST_FpP80m;   // pops
   } else if (RC == &X86::RFP64RegClass || RC == &X86::RSTRegClass) {
+    /// FIXME spilling long double values as 64 bit does not work.
+    /// We need RST80, unfortunately.
     Opc = X86::ST_Fp64m;
   } else if (RC == &X86::RFP32RegClass) {
     Opc = X86::ST_Fp32m;
@@ -205,6 +209,8 @@ void X86RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
     Opc = X86::MOV32_rm;
   } else if (RC == &X86::GR16_RegClass) {
     Opc = X86::MOV16_rm;
+  } else if (RC == &X86::RFP80RegClass) {
+    Opc = X86::LD_Fp80m;
   } else if (RC == &X86::RFP64RegClass || RC == &X86::RSTRegClass) {
     Opc = X86::LD_Fp64m;
   } else if (RC == &X86::RFP32RegClass) {
@@ -245,6 +251,8 @@ void X86RegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
     Opc = X86::MOV_Fp3232;
   } else if (RC == &X86::RFP64RegClass || RC == &X86::RSTRegClass) {
     Opc = X86::MOV_Fp6464;
+  } else if (RC == &X86::RFP80RegClass) {
+    Opc = X86::MOV_Fp8080;
   } else if (RC == &X86::FR32RegClass) {
     Opc = X86::FsMOVAPSrr;
   } else if (RC == &X86::FR64RegClass) {
index 034363527000d26355794fbff8fc8b47de725a7f..ab6262b47e53bf301a63169254ffd5e9cff504c2 100644 (file)
@@ -1949,7 +1949,8 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
       if (RHSC->isNullValue())
         return ReplaceInstUsesWith(I, LHS);
     } else if (ConstantFP *CFP = dyn_cast<ConstantFP>(RHSC)) {
-      if (CFP->isExactlyValue(-0.0))
+      if (CFP->isExactlyValue(ConstantFP::getNegativeZero
+                              (I.getType())->getValueAPF()))
         return ReplaceInstUsesWith(I, LHS);
     }
 
@@ -2349,8 +2350,10 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
 
       // "In IEEE floating point, x*1 is not equivalent to x for nans.  However,
       // ANSI says we can drop signals, so we can do this anyway." (from GCC)
-      if (Op1F->isExactlyValue(1.0))
-        return ReplaceInstUsesWith(I, Op0);  // Eliminate 'mul double %X, 1.0'
+      // We need a better interface for long double here.
+      if (Op1->getType() == Type::FloatTy || Op1->getType() == Type::DoubleTy)
+        if (Op1F->isExactlyValue(1.0))
+          return ReplaceInstUsesWith(I, Op0);  // Eliminate 'mul double %X, 1.0'
     }
     
     if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0))
index c546045454218ebcd8bf6843f5f2b0703e627a1e..2bcd7b68b75f294e5f7a93445faecae84a870831 100644 (file)
@@ -103,17 +103,19 @@ bool Constant::ContainsRelocations() const {
 
 // Static constructor to create a '0' constant of arbitrary type...
 Constant *Constant::getNullValue(const Type *Ty) {
+  static uint64_t zero[2] = {0, 0};
   switch (Ty->getTypeID()) {
   case Type::IntegerTyID:
     return ConstantInt::get(Ty, 0);
   case Type::FloatTyID:
-    return ConstantFP::get(Ty, APFloat(0.0f));
+    return ConstantFP::get(Ty, APFloat(APInt(32, 0)));
   case Type::DoubleTyID:
-    return ConstantFP::get(Ty, APFloat(0.0));
+    return ConstantFP::get(Ty, APFloat(APInt(64, 0)));
   case Type::X86_FP80TyID:
-  case Type::PPC_FP128TyID:
+    return ConstantFP::get(Ty, APFloat(APInt(80, 2, zero)));
   case Type::FP128TyID:
-    return ConstantFP::get(Ty, APFloat(0.0));   //FIXME
+  case Type::PPC_FP128TyID:
+    return ConstantFP::get(Ty, APFloat(APInt(128, 2, zero)));
   case Type::PointerTyID:
     return ConstantPointerNull::get(cast<PointerType>(Ty));
   case Type::StructTyID:
@@ -259,6 +261,12 @@ bool ConstantFP::isNullValue() const {
   return Val.isZero() && !Val.isNegative();
 }
 
+ConstantFP *ConstantFP::getNegativeZero(const Type *Ty) {
+  APFloat apf = cast <ConstantFP>(Constant::getNullValue(Ty))->getValueAPF();
+  apf.changeSign();
+  return ConstantFP::get(Ty, apf);
+}
+
 bool ConstantFP::isExactlyValue(const APFloat& V) const {
   return Val.bitwiseIsEqual(V);
 }
@@ -1925,15 +1933,12 @@ Constant *ConstantExpr::getZeroValueForNegationExpr(const Type *Ty) {
   if (const VectorType *PTy = dyn_cast<VectorType>(Ty))
     if (PTy->getElementType()->isFloatingPoint()) {
       std::vector<Constant*> zeros(PTy->getNumElements(),
-                                   ConstantFP::get(PTy->getElementType(),
-                                       PTy->getElementType()==Type::FloatTy ?
-                                       APFloat(-0.0f) : APFloat(0.0)));
+                           ConstantFP::getNegativeZero(PTy->getElementType()));
       return ConstantVector::get(PTy, zeros);
     }
 
-  if (Ty->isFloatingPoint())
-    return ConstantFP::get(Ty, Ty==Type::FloatTy ? APFloat(-0.0f) : 
-                                                   APFloat(-0.0));
+  if (Ty->isFloatingPoint()) 
+    return ConstantFP::getNegativeZero(Ty);
 
   return Constant::getNullValue(Ty);
 }