aboutsummaryrefslogtreecommitdiffstats
path: root/lib/VMCore
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2007-09-06 18:13:44 +0000
committerDale Johannesen <dalej@apple.com>2007-09-06 18:13:44 +0000
commit43421b3dd70af5b70e71816521f37502c397cc65 (patch)
treeb314e17b0444f33dc3be37eaeaeaa8ea7dd1d17e /lib/VMCore
parent325be7c608a37d87e4f3d731e11fa3dd34f529b5 (diff)
downloadexternal_llvm-43421b3dd70af5b70e71816521f37502c397cc65.zip
external_llvm-43421b3dd70af5b70e71816521f37502c397cc65.tar.gz
external_llvm-43421b3dd70af5b70e71816521f37502c397cc65.tar.bz2
Next round of APFloat changes.
Use APFloat in UpgradeParser and AsmParser. Change all references to ConstantFP to use the APFloat interface rather than double. Remove the ConstantFP double interfaces. Use APFloat functions for constant folding arithmetic and comparisons. (There are still way too many places APFloat is just a wrapper around host float/double, but we're getting there.) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41747 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/AsmWriter.cpp9
-rw-r--r--lib/VMCore/ConstantFold.cpp163
-rw-r--r--lib/VMCore/Constants.cpp37
3 files changed, 111 insertions, 98 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index 9286e15..a7b1239 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -486,7 +486,10 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV,
// make sure that we only output it in exponential format if we can parse
// the value back and get the same value.
//
- std::string StrVal = ftostr(CFP->getValue());
+ bool isDouble = &CFP->getValueAPF().getSemantics() == &APFloat::IEEEdouble;
+ double Val = (isDouble) ? CFP->getValueAPF().convertToDouble() :
+ CFP->getValueAPF().convertToFloat();
+ std::string StrVal = ftostr(CFP->getValueAPF());
// Check to make sure that the stringized number is not some string like
// "Inf" or NaN, that atof will accept, but the lexer will not. Check that
@@ -496,7 +499,7 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV,
((StrVal[0] == '-' || StrVal[0] == '+') &&
(StrVal[1] >= '0' && StrVal[1] <= '9')))
// Reparse stringized version!
- if (atof(StrVal.c_str()) == CFP->getValue()) {
+ if (atof(StrVal.c_str()) == Val) {
Out << StrVal;
return;
}
@@ -505,7 +508,7 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV,
// output the string in hexadecimal format!
assert(sizeof(double) == sizeof(uint64_t) &&
"assuming that double is 64 bits!");
- Out << "0x" << utohexstr(DoubleToBits(CFP->getValue()));
+ Out << "0x" << utohexstr(DoubleToBits(Val));
} else if (isa<ConstantAggregateZero>(CV)) {
Out << "zeroinitializer";
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index fb2e65f..5686a0e 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -68,7 +68,7 @@ static Constant *CastConstantVector(ConstantVector *CV,
for (unsigned i = 0; i != SrcNumElts; ++i) {
ConstantInt *CI = cast<ConstantInt>(CV->getOperand(i));
double V = CI->getValue().bitsToDouble();
- Result.push_back(ConstantFP::get(Type::DoubleTy, V));
+ Result.push_back(ConstantFP::get(Type::DoubleTy, APFloat(V)));
}
return ConstantVector::get(Result);
}
@@ -76,7 +76,7 @@ static Constant *CastConstantVector(ConstantVector *CV,
for (unsigned i = 0; i != SrcNumElts; ++i) {
ConstantInt *CI = cast<ConstantInt>(CV->getOperand(i));
float V = CI->getValue().bitsToFloat();
- Result.push_back(ConstantFP::get(Type::FloatTy, V));
+ Result.push_back(ConstantFP::get(Type::FloatTy, APFloat(V)));
}
return ConstantVector::get(Result);
}
@@ -87,7 +87,8 @@ static Constant *CastConstantVector(ConstantVector *CV,
if (SrcEltTy->getTypeID() == Type::DoubleTyID) {
for (unsigned i = 0; i != SrcNumElts; ++i) {
uint64_t V =
- DoubleToBits(cast<ConstantFP>(CV->getOperand(i))->getValue());
+ DoubleToBits(cast<ConstantFP>(CV->getOperand(i))->
+ getValueAPF().convertToDouble());
Constant *C = ConstantInt::get(Type::Int64Ty, V);
Result.push_back(ConstantExpr::getBitCast(C, DstEltTy ));
}
@@ -96,7 +97,8 @@ static Constant *CastConstantVector(ConstantVector *CV,
assert(SrcEltTy->getTypeID() == Type::FloatTyID);
for (unsigned i = 0; i != SrcNumElts; ++i) {
- uint32_t V = FloatToBits(cast<ConstantFP>(CV->getOperand(i))->getValue());
+ uint32_t V = FloatToBits(cast<ConstantFP>(CV->getOperand(i))->
+ getValueAPF().convertToFloat());
Constant *C = ConstantInt::get(Type::Int32Ty, V);
Result.push_back(ConstantExpr::getBitCast(C, DstEltTy));
}
@@ -175,20 +177,31 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
switch (opc) {
case Instruction::FPTrunc:
case Instruction::FPExt:
- if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V))
- return ConstantFP::get(DestTy, FPC->getValue());
+ if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V)) {
+ APFloat Val = FPC->getValueAPF();
+ Val.convert(DestTy==Type::FloatTy ? APFloat::IEEEsingle :
+ APFloat::IEEEdouble,
+ APFloat::rmNearestTiesToEven);
+ return ConstantFP::get(DestTy, Val);
+ }
return 0; // Can't fold.
case Instruction::FPToUI:
if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V)) {
+ APFloat V = FPC->getValueAPF();
+ bool isDouble = &V.getSemantics()==&APFloat::IEEEdouble;
uint32_t DestBitWidth = cast<IntegerType>(DestTy)->getBitWidth();
- APInt Val(APIntOps::RoundDoubleToAPInt(FPC->getValue(), DestBitWidth));
+ APInt Val(APIntOps::RoundDoubleToAPInt(isDouble ? V.convertToDouble() :
+ (double)V.convertToFloat(), DestBitWidth));
return ConstantInt::get(Val);
}
return 0; // Can't fold.
case Instruction::FPToSI:
if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V)) {
+ APFloat V = FPC->getValueAPF();
+ bool isDouble = &V.getSemantics()==&APFloat::IEEEdouble;
uint32_t DestBitWidth = cast<IntegerType>(DestTy)->getBitWidth();
- APInt Val(APIntOps::RoundDoubleToAPInt(FPC->getValue(), DestBitWidth));
+ APInt Val(APIntOps::RoundDoubleToAPInt(isDouble ? V.convertToDouble() :
+ (double)V.convertToFloat(), DestBitWidth));
return ConstantInt::get(Val);
}
return 0; // Can't fold.
@@ -201,12 +214,22 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
return ConstantInt::get(DestTy, 0);
return 0; // Other pointer types cannot be casted
case Instruction::UIToFP:
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
- return ConstantFP::get(DestTy, CI->getValue().roundToDouble());
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+ if (DestTy==Type::FloatTy)
+ return ConstantFP::get(DestTy,
+ APFloat((float)CI->getValue().roundToDouble()));
+ else
+ return ConstantFP::get(DestTy, APFloat(CI->getValue().roundToDouble()));
+ }
return 0;
case Instruction::SIToFP:
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
- return ConstantFP::get(DestTy, CI->getValue().signedRoundToDouble());
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+ double d = CI->getValue().signedRoundToDouble();
+ if (DestTy==Type::FloatTy)
+ return ConstantFP::get(DestTy, APFloat((float)d));
+ else
+ return ConstantFP::get(DestTy, APFloat(d));
+ }
return 0;
case Instruction::ZExt:
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
@@ -309,9 +332,9 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
if (DestTy->isFloatingPoint()) {
if (DestTy == Type::FloatTy)
- return ConstantFP::get(DestTy, CI->getValue().bitsToFloat());
+ return ConstantFP::get(DestTy, APFloat(CI->getValue().bitsToFloat()));
assert(DestTy == Type::DoubleTy && "Unknown FP type!");
- return ConstantFP::get(DestTy, CI->getValue().bitsToDouble());
+ return ConstantFP::get(DestTy, APFloat(CI->getValue().bitsToDouble()));
}
// Otherwise, can't fold this (vector?)
return 0;
@@ -322,11 +345,13 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
// FP -> Integral.
if (DestTy == Type::Int32Ty) {
APInt Val(32, 0);
- return ConstantInt::get(Val.floatToBits(FP->getValue()));
+ return ConstantInt::get(Val.floatToBits(FP->
+ getValueAPF().convertToFloat()));
} else {
assert(DestTy == Type::Int64Ty && "only support f32/f64 for now!");
APInt Val(64, 0);
- return ConstantInt::get(Val.doubleToBits(FP->getValue()));
+ return ConstantInt::get(Val.doubleToBits(FP->
+ getValueAPF().convertToDouble()));
}
}
return 0;
@@ -660,39 +685,50 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
}
} else if (const ConstantFP *CFP1 = dyn_cast<ConstantFP>(C1)) {
if (const ConstantFP *CFP2 = dyn_cast<ConstantFP>(C2)) {
- double C1Val = CFP1->getValue();
- double C2Val = CFP2->getValue();
+ APFloat C1V = CFP1->getValueAPF();
+ APFloat C2V = CFP2->getValueAPF();
+ APFloat C3V = C1V; // copy for modification
+ bool isDouble = CFP1->getType()==Type::DoubleTy;
switch (Opcode) {
default:
break;
- case Instruction::Add:
- return ConstantFP::get(CFP1->getType(), C1Val + C2Val);
+ case Instruction::Add:
+ (void)C3V.add(C2V, APFloat::rmNearestTiesToEven);
+ return ConstantFP::get(CFP1->getType(), C3V);
case Instruction::Sub:
- return ConstantFP::get(CFP1->getType(), C1Val - C2Val);
- case Instruction::Mul:
- return ConstantFP::get(CFP1->getType(), C1Val * C2Val);
+ (void)C3V.subtract(C2V, APFloat::rmNearestTiesToEven);
+ return ConstantFP::get(CFP1->getType(), C3V);
+ case Instruction::Mul:
+ (void)C3V.multiply(C2V, APFloat::rmNearestTiesToEven);
+ return ConstantFP::get(CFP1->getType(), C3V);
case Instruction::FDiv:
- if (CFP2->isExactlyValue(0.0) || CFP2->isExactlyValue(-0.0))
- if (CFP1->isExactlyValue(0.0) || CFP1->isExactlyValue(-0.0))
+ // FIXME better to look at the return code
+ if (C2V.isZero())
+ if (C1V.isZero())
// IEEE 754, Section 7.1, #4
- return ConstantFP::get(CFP1->getType(),
- std::numeric_limits<double>::quiet_NaN());
- else if (CFP2->isExactlyValue(-0.0) || C1Val < 0.0)
+ return ConstantFP::get(CFP1->getType(), isDouble ?
+ APFloat(std::numeric_limits<double>::quiet_NaN()) :
+ APFloat(std::numeric_limits<float>::quiet_NaN()));
+ else if (C2V.isNegZero() || C1V.isNegative())
// IEEE 754, Section 7.2, negative infinity case
- return ConstantFP::get(CFP1->getType(),
- -std::numeric_limits<double>::infinity());
+ return ConstantFP::get(CFP1->getType(), isDouble ?
+ APFloat(-std::numeric_limits<double>::infinity()) :
+ APFloat(-std::numeric_limits<float>::infinity()));
else
// IEEE 754, Section 7.2, positive infinity case
- return ConstantFP::get(CFP1->getType(),
- std::numeric_limits<double>::infinity());
- return ConstantFP::get(CFP1->getType(), C1Val / C2Val);
+ return ConstantFP::get(CFP1->getType(), isDouble ?
+ APFloat(std::numeric_limits<double>::infinity()) :
+ APFloat(std::numeric_limits<float>::infinity()));
+ (void)C3V.divide(C2V, APFloat::rmNearestTiesToEven);
+ return ConstantFP::get(CFP1->getType(), C3V);
case Instruction::FRem:
- if (CFP2->isExactlyValue(0.0) || CFP2->isExactlyValue(-0.0))
+ if (C2V.isZero())
// IEEE 754, Section 7.1, #5
- return ConstantFP::get(CFP1->getType(),
- std::numeric_limits<double>::quiet_NaN());
- return ConstantFP::get(CFP1->getType(), std::fmod(C1Val, C2Val));
-
+ return ConstantFP::get(CFP1->getType(), isDouble ?
+ APFloat(std::numeric_limits<double>::quiet_NaN()) :
+ APFloat(std::numeric_limits<float>::quiet_NaN()));
+ (void)C3V.mod(C2V, APFloat::rmNearestTiesToEven);
+ return ConstantFP::get(CFP1->getType(), C3V);
}
}
} else if (const ConstantVector *CP1 = dyn_cast<ConstantVector>(C1)) {
@@ -1123,52 +1159,47 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
case ICmpInst::ICMP_UGE:return ConstantInt::get(Type::Int1Ty, V1.uge(V2));
}
} else if (isa<ConstantFP>(C1) && isa<ConstantFP>(C2)) {
- double C1Val = cast<ConstantFP>(C1)->getValue();
- double C2Val = cast<ConstantFP>(C2)->getValue();
+ APFloat C1V = cast<ConstantFP>(C1)->getValueAPF();
+ APFloat C2V = cast<ConstantFP>(C2)->getValueAPF();
+ APFloat::cmpResult R = C1V.compare(C2V);
switch (pred) {
default: assert(0 && "Invalid FCmp Predicate"); return 0;
case FCmpInst::FCMP_FALSE: return ConstantInt::getFalse();
case FCmpInst::FCMP_TRUE: return ConstantInt::getTrue();
case FCmpInst::FCMP_UNO:
- return ConstantInt::get(Type::Int1Ty, C1Val != C1Val || C2Val != C2Val);
+ return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered);
case FCmpInst::FCMP_ORD:
- return ConstantInt::get(Type::Int1Ty, C1Val == C1Val && C2Val == C2Val);
+ return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpUnordered);
case FCmpInst::FCMP_UEQ:
- if (C1Val != C1Val || C2Val != C2Val)
- return ConstantInt::getTrue();
- /* FALL THROUGH */
+ return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered ||
+ R==APFloat::cmpEqual);
case FCmpInst::FCMP_OEQ:
- return ConstantInt::get(Type::Int1Ty, C1Val == C2Val);
+ return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpEqual);
case FCmpInst::FCMP_UNE:
- if (C1Val != C1Val || C2Val != C2Val)
- return ConstantInt::getTrue();
- /* FALL THROUGH */
+ return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpEqual);
case FCmpInst::FCMP_ONE:
- return ConstantInt::get(Type::Int1Ty, C1Val != C2Val);
+ return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpLessThan ||
+ R==APFloat::cmpGreaterThan);
case FCmpInst::FCMP_ULT:
- if (C1Val != C1Val || C2Val != C2Val)
- return ConstantInt::getTrue();
- /* FALL THROUGH */
+ return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered ||
+ R==APFloat::cmpLessThan);
case FCmpInst::FCMP_OLT:
- return ConstantInt::get(Type::Int1Ty, C1Val < C2Val);
+ return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpLessThan);
case FCmpInst::FCMP_UGT:
- if (C1Val != C1Val || C2Val != C2Val)
- return ConstantInt::getTrue();
- /* FALL THROUGH */
+ return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered ||
+ R==APFloat::cmpGreaterThan);
case FCmpInst::FCMP_OGT:
- return ConstantInt::get(Type::Int1Ty, C1Val > C2Val);
+ return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpGreaterThan);
case FCmpInst::FCMP_ULE:
- if (C1Val != C1Val || C2Val != C2Val)
- return ConstantInt::getTrue();
- /* FALL THROUGH */
+ return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpGreaterThan);
case FCmpInst::FCMP_OLE:
- return ConstantInt::get(Type::Int1Ty, C1Val <= C2Val);
+ return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpLessThan ||
+ R==APFloat::cmpEqual);
case FCmpInst::FCMP_UGE:
- if (C1Val != C1Val || C2Val != C2Val)
- return ConstantInt::getTrue();
- /* FALL THROUGH */
+ return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpLessThan);
case FCmpInst::FCMP_OGE:
- return ConstantInt::get(Type::Int1Ty, C1Val >= C2Val);
+ return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpGreaterThan ||
+ R==APFloat::cmpEqual);
}
} else if (const ConstantVector *CP1 = dyn_cast<ConstantVector>(C1)) {
if (const ConstantVector *CP2 = dyn_cast<ConstantVector>(C2)) {
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index f7cbe82..1708e46 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -107,11 +107,13 @@ Constant *Constant::getNullValue(const Type *Ty) {
case Type::IntegerTyID:
return ConstantInt::get(Ty, 0);
case Type::FloatTyID:
+ return ConstantFP::get(Ty, APFloat(0.0f));
case Type::DoubleTyID:
+ return ConstantFP::get(Ty, APFloat(0.0));
case Type::X86_FP80TyID:
case Type::PPC_FP128TyID:
case Type::FP128TyID:
- return ConstantFP::get(Ty, 0.0);
+ return ConstantFP::get(Ty, APFloat(0.0)); //FIXME
case Type::PointerTyID:
return ConstantPointerNull::get(cast<PointerType>(Ty));
case Type::StructTyID:
@@ -238,11 +240,6 @@ ConstantInt *ConstantInt::get(const APInt& V) {
// ConstantFP
//===----------------------------------------------------------------------===//
-
-ConstantFP::ConstantFP(const Type *Ty, double V)
- : Constant(Ty, ConstantFPVal, 0, 0),
- Val(Ty==Type::FloatTy ? APFloat((float)V) : APFloat(V)) {
-}
ConstantFP::ConstantFP(const Type *Ty, const APFloat& V)
: Constant(Ty, ConstantFPVal, 0, 0), Val(V) {
// temporary
@@ -293,27 +290,6 @@ 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, APFloat((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, APFloat(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)
@@ -1934,12 +1910,15 @@ 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::get(PTy->getElementType(),
+ PTy->getElementType()==Type::FloatTy ?
+ APFloat(-0.0f) : APFloat(0.0)));
return ConstantVector::get(PTy, zeros);
}
if (Ty->isFloatingPoint())
- return ConstantFP::get(Ty, -0.0);
+ return ConstantFP::get(Ty, Ty==Type::FloatTy ? APFloat(-0.0f) :
+ APFloat(-0.0));
return Constant::getNullValue(Ty);
}