Fix bug in updating dominance frontier after loop
[oota-llvm.git] / lib / VMCore / Constants.cpp
index fc3f5c92b6362919e9adfc73ea035792fd0aa0b1..28b7e45bf55fa2b3db57bfd088d1ffeff7859430 100644 (file)
@@ -103,15 +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(APInt(32, 0)));
   case Type::DoubleTyID:
+    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, 0.0);
+  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:
@@ -199,9 +203,12 @@ namespace {
     static inline KeyTy getEmptyKey() { return KeyTy(APInt(1,0), 0); }
     static inline KeyTy getTombstoneKey() { return KeyTy(APInt(1,1), 0); }
     static unsigned getHashValue(const KeyTy &Key) {
-      return DenseMapKeyInfo<void*>::getHashValue(Key.type) ^ 
+      return DenseMapInfo<void*>::getHashValue(Key.type) ^ 
         Key.val.getHashValue();
     }
+    static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
+      return LHS == RHS;
+    }
     static bool isPod() { return false; }
   };
 }
@@ -238,17 +245,33 @@ ConstantInt *ConstantInt::get(const APInt& V) {
 //                                ConstantFP
 //===----------------------------------------------------------------------===//
 
-
-ConstantFP::ConstantFP(const Type *Ty, double V)
-  : Constant(Ty, ConstantFPVal, 0, 0), Val(APFloat(V)) {
+ConstantFP::ConstantFP(const Type *Ty, const APFloat& V)
+  : Constant(Ty, ConstantFPVal, 0, 0), Val(V) {
+  // temporary
+  if (Ty==Type::FloatTy)
+    assert(&V.getSemantics()==&APFloat::IEEEsingle);
+  else if (Ty==Type::DoubleTy)
+    assert(&V.getSemantics()==&APFloat::IEEEdouble);
+  else if (Ty==Type::X86_FP80Ty)
+    assert(&V.getSemantics()==&APFloat::x87DoubleExtended);
+  else if (Ty==Type::FP128Ty)
+    assert(&V.getSemantics()==&APFloat::IEEEquad);
+  else
+    assert(0);
 }
 
 bool ConstantFP::isNullValue() const {
   return Val.isZero() && !Val.isNegative();
 }
 
-bool ConstantFP::isExactlyValue(double V) const {
-  return Val == APFloat(V);
+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);
 }
 
 namespace {
@@ -258,7 +281,7 @@ namespace {
       KeyTy(const APFloat& V) : val(V){}
       KeyTy(const KeyTy& that) : val(that.val) {}
       bool operator==(const KeyTy& that) const {
-        return this->val == that.val;
+        return this->val.bitwiseIsEqual(that.val);
       }
       bool operator!=(const KeyTy& that) const {
         return !this->operator==(that);
@@ -273,6 +296,9 @@ namespace {
     static unsigned getHashValue(const KeyTy &Key) {
       return Key.val.getHashValue();
     }
+    static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
+      return LHS == RHS;
+    }
     static bool isPod() { return false; }
   };
 }
@@ -284,28 +310,25 @@ typedef DenseMap<DenseMapAPFloatKeyInfo::KeyTy, ConstantFP*,
 
 static ManagedStatic<FPMapTy> FPConstants;
 
-ConstantFP *ConstantFP::get(const Type *Ty, double V) {
-  if (Ty == Type::FloatTy) {
-    DenseMapAPFloatKeyInfo::KeyTy Key(APFloat((float)V));
-    ConstantFP *&Slot = (*FPConstants)[Key];
-    if (Slot) return Slot;
-    return Slot = new ConstantFP(Ty, (float)V);
-  } else if (Ty == Type::DoubleTy) {
-    // Without the redundant cast, the following is taken to be
-    // a function declaration.  What a language.
-    DenseMapAPFloatKeyInfo::KeyTy Key(APFloat((double)V));
-    ConstantFP *&Slot = (*FPConstants)[Key];
-    if (Slot) return Slot;
-    return Slot = new ConstantFP(Ty, V);
-  } else if (Ty == Type::X86_FP80Ty ||
-             Ty == Type::PPC_FP128Ty || Ty == Type::FP128Ty) {
-    assert(0 && "Long double constants not handled yet.");
-  } else {
-    assert(0 && "Unknown FP Type!");
-  }
+ConstantFP *ConstantFP::get(const Type *Ty, const APFloat& V) {
+  // temporary
+  if (Ty==Type::FloatTy)
+    assert(&V.getSemantics()==&APFloat::IEEEsingle);
+  else if (Ty==Type::DoubleTy)
+    assert(&V.getSemantics()==&APFloat::IEEEdouble);
+  else if (Ty==Type::X86_FP80Ty)
+    assert(&V.getSemantics()==&APFloat::x87DoubleExtended);
+  else if (Ty==Type::FP128Ty)
+    assert(&V.getSemantics()==&APFloat::IEEEquad);
+  else
+    assert(0);
+  
+  DenseMapAPFloatKeyInfo::KeyTy Key(V);
+  ConstantFP *&Slot = (*FPConstants)[Key];
+  if (Slot) return Slot;
+  return Slot = new ConstantFP(Ty, V);
 }
 
-
 //===----------------------------------------------------------------------===//
 //                            ConstantXXX Classes
 //===----------------------------------------------------------------------===//
@@ -699,18 +722,31 @@ bool ConstantInt::isValueValidForType(const Type *Ty, int64_t Val) {
   return (Val >= Min && Val <= Max);
 }
 
-bool ConstantFP::isValueValidForType(const Type *Ty, double Val) {
+bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) {
+  // convert modifies in place, so make a copy.
+  APFloat Val2 = APFloat(Val);
   switch (Ty->getTypeID()) {
   default:
     return false;         // These can't be represented as floating point!
 
-    // TODO: Figure out how to test if we can use a shorter type instead!
+  // FIXME rounding mode needs to be more flexible
   case Type::FloatTyID:
+    return &Val2.getSemantics() == &APFloat::IEEEsingle ||
+           Val2.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven) == 
+              APFloat::opOK;
   case Type::DoubleTyID:
+    return &Val2.getSemantics() == &APFloat::IEEEsingle || 
+           &Val2.getSemantics() == &APFloat::IEEEdouble ||
+           Val2.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven) == 
+             APFloat::opOK;
   case Type::X86_FP80TyID:
-  case Type::PPC_FP128TyID:
+    return &Val2.getSemantics() == &APFloat::IEEEsingle || 
+           &Val2.getSemantics() == &APFloat::IEEEdouble ||
+           &Val2.getSemantics() == &APFloat::x87DoubleExtended;
   case Type::FP128TyID:
-    return true;
+    return &Val2.getSemantics() == &APFloat::IEEEsingle || 
+           &Val2.getSemantics() == &APFloat::IEEEdouble ||
+           &Val2.getSemantics() == &APFloat::IEEEquad;
   }
 }
 
@@ -1768,7 +1804,7 @@ Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C,
 Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C,
                                            Value* const *Idxs,
                                            unsigned NumIdx) {
-  assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, NumIdx, true) &&
+  assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx, true) &&
          "GEP indices invalid!");
 
   if (Constant *FC = ConstantFoldGetElementPtr(C, (Constant**)Idxs, NumIdx))
@@ -1790,7 +1826,7 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs,
                                          unsigned NumIdx) {
   // Get the result type of the getelementptr!
   const Type *Ty = 
-    GetElementPtrInst::getIndexedType(C->getType(), Idxs, NumIdx, true);
+    GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx, true);
   assert(Ty && "GEP indices invalid!");
   return getGetElementPtrTy(PointerType::get(Ty), C, Idxs, NumIdx);
 }
@@ -1903,12 +1939,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(),-0.0));
+                           ConstantFP::getNegativeZero(PTy->getElementType()));
       return ConstantVector::get(PTy, zeros);
     }
 
-  if (Ty->isFloatingPoint())
-    return ConstantFP::get(Ty, -0.0);
+  if (Ty->isFloatingPoint()) 
+    return ConstantFP::getNegativeZero(Ty);
 
   return Constant::getNullValue(Ty);
 }