// 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:
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; }
};
}
// temporary
if (Ty==Type::FloatTy)
assert(&V.getSemantics()==&APFloat::IEEEsingle);
- else
+ 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();
}
+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);
}
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; }
};
}
// temporary
if (Ty==Type::FloatTy)
assert(&V.getSemantics()==&APFloat::IEEEsingle);
- else
+ 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];
&Val2.getSemantics() == &APFloat::IEEEdouble ||
Val2.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven) ==
APFloat::opOK;
- // TODO: Figure out how to test if we can use a shorter type instead!
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;
}
}
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);
}