aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/ADT/APFloat.h6
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h3
-rw-r--r--lib/AsmParser/llvmAsmParser.y14
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp5
-rw-r--r--lib/CodeGen/SelectionDAG/FastISel.cpp12
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp23
-rw-r--r--lib/ExecutionEngine/ExecutionEngine.cpp3
-rw-r--r--lib/Support/APFloat.cpp51
-rw-r--r--lib/Target/CBackend/CBackend.cpp3
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp3
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp7
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp4
-rw-r--r--lib/VMCore/ConstantFold.cpp6
-rw-r--r--lib/VMCore/Constants.cpp26
-rw-r--r--lib/VMCore/Core.cpp4
15 files changed, 115 insertions, 55 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
index 8566a57..f6456a0 100644
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -216,9 +216,9 @@ namespace llvm {
void copySign(const APFloat &);
/* Conversions. */
- opStatus convert(const fltSemantics &, roundingMode);
+ opStatus convert(const fltSemantics &, roundingMode, bool *);
opStatus convertToInteger(integerPart *, unsigned int, bool,
- roundingMode) const;
+ roundingMode, bool *) const;
opStatus convertFromAPInt(const APInt &,
bool, roundingMode);
opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
@@ -299,7 +299,7 @@ namespace llvm {
opStatus handleOverflow(roundingMode);
bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool,
- roundingMode) const;
+ roundingMode, bool *) const;
opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
roundingMode);
opStatus convertFromHexadecimalString(const char *, roundingMode);
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 8ab6152..e1d1eda 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -1756,12 +1756,13 @@ public:
/// convenient to write "2.0" and the like. Without this function we'd
/// have to duplicate its logic everywhere it's called.
bool isExactlyValue(double V) const {
+ bool ignored;
// convert is not supported on this type
if (&Value->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble)
return false;
APFloat Tmp(V);
Tmp.convert(Value->getValueAPF().getSemantics(),
- APFloat::rmNearestTiesToEven);
+ APFloat::rmNearestTiesToEven, &ignored);
return isExactlyValue(Tmp);
}
bool isExactlyValue(const APFloat& V) const;
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index 9dc0702..a7a4bc0 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -428,8 +428,11 @@ static Value *getExistingVal(const Type *Ty, const ValID &D) {
// Lexer has no type info, so builds all float and double FP constants
// as double. Fix this here. Long double does not need this.
if (&D.ConstPoolFP->getSemantics() == &APFloat::IEEEdouble &&
- Ty==Type::FloatTy)
- D.ConstPoolFP->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven);
+ Ty==Type::FloatTy) {
+ bool ignored;
+ D.ConstPoolFP->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven,
+ &ignored);
+ }
return ConstantFP::get(*D.ConstPoolFP);
case ValID::ConstNullVal: // Is it a null value?
@@ -1929,8 +1932,11 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
GEN_ERROR("Floating point constant invalid for type");
// Lexer has no type info, so builds all float and double FP constants
// as double. Fix this here. Long double is done right.
- if (&$2->getSemantics()==&APFloat::IEEEdouble && $1==Type::FloatTy)
- $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven);
+ if (&$2->getSemantics()==&APFloat::IEEEdouble && $1==Type::FloatTy) {
+ bool ignored;
+ $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven,
+ &ignored);
+ }
$$ = ConstantFP::get(*$2);
delete $2;
CHECK_FOR_ERROR
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 1321c04..63ada0c 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1000,8 +1000,11 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
// api needed to prevent premature destruction
APInt api = CFP->getValueAPF().bitcastToAPInt();
const uint64_t *p = api.getRawData();
+ // Convert to double so we can print the approximate val as a comment.
APFloat DoubleVal = CFP->getValueAPF();
- DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven);
+ bool ignored;
+ DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
+ &ignored);
if (TD->isBigEndian()) {
O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 48)
<< '\t' << TAI->getCommentString()
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index f9cfeb1..77e9bda 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -93,8 +93,10 @@ unsigned FastISel::getRegForValue(Value *V) {
uint64_t x[2];
uint32_t IntBitWidth = IntVT.getSizeInBits();
- if (!Flt.convertToInteger(x, IntBitWidth, /*isSigned=*/true,
- APFloat::rmTowardZero) != APFloat::opOK) {
+ bool isExact;
+ (void) Flt.convertToInteger(x, IntBitWidth, /*isSigned=*/true,
+ APFloat::rmTowardZero, &isExact);
+ if (isExact) {
APInt IntVal(IntBitWidth, 2, x);
unsigned IntegerReg = getRegForValue(ConstantInt::get(IntVal));
@@ -711,8 +713,10 @@ unsigned FastISel::FastEmit_rf_(MVT::SimpleValueType VT, ISD::NodeType Opcode,
uint64_t x[2];
uint32_t IntBitWidth = IntVT.getSizeInBits();
- if (Flt.convertToInteger(x, IntBitWidth, /*isSigned=*/true,
- APFloat::rmTowardZero) != APFloat::opOK)
+ bool isExact;
+ (void) Flt.convertToInteger(x, IntBitWidth, /*isSigned=*/true,
+ APFloat::rmTowardZero, &isExact);
+ if (!isExact)
return 0;
APInt IntVal(IntBitWidth, 2, x);
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index cacffe4..f75d392 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -84,8 +84,10 @@ bool ConstantFPSDNode::isValueValidForType(MVT VT,
// convert modifies in place, so make a copy.
APFloat Val2 = APFloat(Val);
- return Val2.convert(*MVTToAPFloatSemantics(VT),
- APFloat::rmNearestTiesToEven) == APFloat::opOK;
+ bool losesInfo;
+ (void) Val2.convert(*MVTToAPFloatSemantics(VT), APFloat::rmNearestTiesToEven,
+ &losesInfo);
+ return !losesInfo;
}
//===----------------------------------------------------------------------===//
@@ -118,7 +120,7 @@ bool ISD::isBuildVectorAllOnes(const SDNode *N) {
return false;
} else if (isa<ConstantFPSDNode>(NotZero)) {
if (!cast<ConstantFPSDNode>(NotZero)->getValueAPF().
- convertToAPInt().isAllOnesValue())
+ bitcastToAPInt().isAllOnesValue())
return false;
} else
return false;
@@ -2124,29 +2126,32 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, SDValue Operand) {
V.clearSign();
return getConstantFP(V, VT);
case ISD::FP_ROUND:
- case ISD::FP_EXTEND:
+ case ISD::FP_EXTEND: {
+ bool ignored;
// This can return overflow, underflow, or inexact; we don't care.
// FIXME need to be more flexible about rounding mode.
(void)V.convert(*MVTToAPFloatSemantics(VT),
- APFloat::rmNearestTiesToEven);
+ APFloat::rmNearestTiesToEven, &ignored);
return getConstantFP(V, VT);
+ }
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT: {
integerPart x;
+ bool ignored;
assert(integerPartWidth >= 64);
// FIXME need to be more flexible about rounding mode.
APFloat::opStatus s = V.convertToInteger(&x, 64U,
Opcode==ISD::FP_TO_SINT,
- APFloat::rmTowardZero);
+ APFloat::rmTowardZero, &ignored);
if (s==APFloat::opInvalidOp) // inexact is OK, in fact usual
break;
return getConstant(x, VT);
}
case ISD::BIT_CONVERT:
if (VT == MVT::i32 && C->getValueType(0) == MVT::f32)
- return getConstant((uint32_t)V.convertToAPInt().getZExtValue(), VT);
+ return getConstant((uint32_t)V.bitcastToAPInt().getZExtValue(), VT);
else if (VT == MVT::i64 && C->getValueType(0) == MVT::f64)
- return getConstant(V.convertToAPInt().getZExtValue(), VT);
+ return getConstant(V.bitcastToAPInt().getZExtValue(), VT);
break;
}
}
@@ -5245,7 +5250,7 @@ void SDNode::print(raw_ostream &OS, const SelectionDAG *G) const {
OS << '<' << CSDN->getValueAPF().convertToDouble() << '>';
else {
OS << "<APFloat(";
- CSDN->getValueAPF().convertToAPInt().dump();
+ CSDN->getValueAPF().bitcastToAPInt().dump();
OS << ")>";
}
} else if (const GlobalAddressSDNode *GADN =
diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp
index 0731672..acc89c9 100644
--- a/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -498,9 +498,10 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
else if (Op0->getType() == Type::X86_FP80Ty) {
APFloat apf = APFloat(GV.IntVal);
uint64_t v;
+ bool ignored;
(void)apf.convertToInteger(&v, BitWidth,
CE->getOpcode()==Instruction::FPToSI,
- APFloat::rmTowardZero);
+ APFloat::rmTowardZero, &ignored);
GV.IntVal = v; // endian?
}
return GV;
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index a8691f4..a65e55a 100644
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -788,6 +788,7 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend)
integerPart scratch[4];
integerPart *fullSignificand;
lostFraction lost_fraction;
+ bool ignored;
assert(semantics == rhs.semantics);
@@ -836,7 +837,7 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend)
semantics = &extendedSemantics;
APFloat extendedAddend(*addend);
- status = extendedAddend.convert(extendedSemantics, rmTowardZero);
+ status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored);
assert(status == opOK);
lost_fraction = addOrSubtractSignificand(extendedAddend, false);
@@ -1528,8 +1529,9 @@ APFloat::mod(const APFloat &rhs, roundingMode rounding_mode)
int parts = partCount();
integerPart *x = new integerPart[parts];
+ bool ignored;
fs = V.convertToInteger(x, parts * integerPartWidth, true,
- rmNearestTiesToEven);
+ rmNearestTiesToEven, &ignored);
if (fs==opInvalidOp)
return fs;
@@ -1670,9 +1672,16 @@ APFloat::compare(const APFloat &rhs) const
return result;
}
+/// APFloat::convert - convert a value of one floating point type to another.
+/// The return value corresponds to the IEEE754 exceptions. *losesInfo
+/// records whether the transformation lost information, i.e. whether
+/// converting the result back to the original type will produce the
+/// original value (this is almost the same as return value==fsOK, but there
+/// are edge cases where this is not so).
+
APFloat::opStatus
APFloat::convert(const fltSemantics &toSemantics,
- roundingMode rounding_mode)
+ roundingMode rounding_mode, bool *losesInfo)
{
lostFraction lostFraction;
unsigned int newPartCount, oldPartCount;
@@ -1718,38 +1727,41 @@ APFloat::convert(const fltSemantics &toSemantics,
exponent += toSemantics.precision - semantics->precision;
semantics = &toSemantics;
fs = normalize(rounding_mode, lostFraction);
+ *losesInfo = (fs != opOK);
} else if (category == fcNaN) {
int shift = toSemantics.precision - semantics->precision;
// Do this now so significandParts gets the right answer
const fltSemantics *oldSemantics = semantics;
semantics = &toSemantics;
- fs = opOK;
+ *losesInfo = false;
// No normalization here, just truncate
if (shift>0)
APInt::tcShiftLeft(significandParts(), newPartCount, shift);
else if (shift < 0) {
unsigned ushift = -shift;
- // We mark this as Inexact if we are losing information. This happens
+ // Figure out if we are losing information. This happens
// if are shifting out something other than 0s, or if the x87 long
// double input did not have its integer bit set (pseudo-NaN), or if the
// x87 long double input did not have its QNan bit set (because the x87
// hardware sets this bit when converting a lower-precision NaN to
// x87 long double).
if (APInt::tcLSB(significandParts(), newPartCount) < ushift)
- fs = opInexact;
+ *losesInfo = true;
if (oldSemantics == &APFloat::x87DoubleExtended &&
(!(*significandParts() & 0x8000000000000000ULL) ||
!(*significandParts() & 0x4000000000000000ULL)))
- fs = opInexact;
+ *losesInfo = true;
APInt::tcShiftRight(significandParts(), newPartCount, ushift);
}
// gcc forces the Quiet bit on, which means (float)(double)(float_sNan)
// does not give you back the same bits. This is dubious, and we
// don't currently do it. You're really supposed to get
// an invalid operation signal at runtime, but nobody does that.
+ fs = opOK;
} else {
semantics = &toSemantics;
fs = opOK;
+ *losesInfo = false;
}
return fs;
@@ -1768,7 +1780,8 @@ APFloat::convert(const fltSemantics &toSemantics,
APFloat::opStatus
APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width,
bool isSigned,
- roundingMode rounding_mode) const
+ roundingMode rounding_mode,
+ bool *isExact) const
{
lostFraction lost_fraction;
const integerPart *src;
@@ -1776,6 +1789,8 @@ APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width,
assertArithmeticOK(*semantics);
+ *isExact = false;
+
/* Handle the three special cases first. */
if(category == fcInfinity || category == fcNaN)
return opInvalidOp;
@@ -1785,7 +1800,8 @@ APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width,
if(category == fcZero) {
APInt::tcSet(parts, 0, dstPartsCount);
// Negative zero can't be represented as an int.
- return sign ? opInexact : opOK;
+ *isExact = !sign;
+ return opOK;
}
src = significandParts();
@@ -1857,24 +1873,31 @@ APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width,
return opInvalidOp;
}
- if (lost_fraction == lfExactlyZero)
+ if (lost_fraction == lfExactlyZero) {
+ *isExact = true;
return opOK;
- else
+ } else
return opInexact;
}
/* Same as convertToSignExtendedInteger, except we provide
deterministic values in case of an invalid operation exception,
namely zero for NaNs and the minimal or maximal value respectively
- for underflow or overflow. */
+ for underflow or overflow.
+ The *isExact output tells whether the result is exact, in the sense
+ that converting it back to the original floating point type produces
+ the original value. This is almost equivalent to result==opOK,
+ except for negative zeroes.
+*/
APFloat::opStatus
APFloat::convertToInteger(integerPart *parts, unsigned int width,
bool isSigned,
- roundingMode rounding_mode) const
+ roundingMode rounding_mode, bool *isExact) const
{
opStatus fs;
- fs = convertToSignExtendedInteger(parts, width, isSigned, rounding_mode);
+ fs = convertToSignExtendedInteger(parts, width, isSigned, rounding_mode,
+ isExact);
if (fs == opInvalidOp) {
unsigned int bits, dstPartsCount;
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index 96ae40c..9a79748 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -832,12 +832,13 @@ void CWriter::printConstantVector(ConstantVector *CP, bool Static) {
// only deal in IEEE FP).
//
static bool isFPCSafeToPrint(const ConstantFP *CFP) {
+ bool ignored;
// Do long doubles in hex 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);
+ APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored);
#if HAVE_PRINTF_A && ENABLE_CBE_PRINTF_A
char Buffer[100];
sprintf(Buffer, "%a", APF.convertToDouble());
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp
index 21e6735..fb83663 100644
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -218,9 +218,10 @@ namespace {
// This makes sure that conversion to/from floating yields the same binary
// result so that we don't lose precision.
void CppWriter::printCFP(const ConstantFP *CFP) {
+ bool ignored;
APFloat APF = APFloat(CFP->getValueAPF()); // copy
if (CFP->getType() == Type::FloatTy)
- APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven);
+ APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored);
Out << "ConstantFP::get(";
Out << "APFloat(";
#if HAVE_PRINTF_A
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index d74588e..d5b2b44 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -482,13 +482,16 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
setOperationAction(ISD::UNDEF, MVT::f80, Expand);
setOperationAction(ISD::FCOPYSIGN, MVT::f80, Expand);
{
+ bool ignored;
APFloat TmpFlt(+0.0);
- TmpFlt.convert(APFloat::x87DoubleExtended, APFloat::rmNearestTiesToEven);
+ TmpFlt.convert(APFloat::x87DoubleExtended, APFloat::rmNearestTiesToEven,
+ &ignored);
addLegalFPImmediate(TmpFlt); // FLD0
TmpFlt.changeSign();
addLegalFPImmediate(TmpFlt); // FLD0/FCHS
APFloat TmpFlt2(+1.0);
- TmpFlt2.convert(APFloat::x87DoubleExtended, APFloat::rmNearestTiesToEven);
+ TmpFlt2.convert(APFloat::x87DoubleExtended, APFloat::rmNearestTiesToEven,
+ &ignored);
addLegalFPImmediate(TmpFlt2); // FLD1
TmpFlt2.changeSign();
addLegalFPImmediate(TmpFlt2); // FLD1/FCHS
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 8cb5e4f..60da031 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -7856,8 +7856,10 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) {
/// FitsInFPType - Return a Constant* for the specified FP constant if it fits
/// in the specified FP type without changing its value.
static Constant *FitsInFPType(ConstantFP *CFP, const fltSemantics &Sem) {
+ bool losesInfo;
APFloat F = CFP->getValueAPF();
- if (F.convert(Sem, APFloat::rmNearestTiesToEven) == APFloat::opOK)
+ (void)F.convert(Sem, APFloat::rmNearestTiesToEven, &losesInfo);
+ if (!losesInfo)
return ConstantFP::get(F);
return 0;
}
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index 9256109..93ee7fe 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -213,13 +213,14 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
case Instruction::FPTrunc:
case Instruction::FPExt:
if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V)) {
+ bool ignored;
APFloat Val = FPC->getValueAPF();
Val.convert(DestTy == Type::FloatTy ? APFloat::IEEEsingle :
DestTy == Type::DoubleTy ? APFloat::IEEEdouble :
DestTy == Type::X86_FP80Ty ? APFloat::x87DoubleExtended :
DestTy == Type::FP128Ty ? APFloat::IEEEquad :
APFloat::Bogus,
- APFloat::rmNearestTiesToEven);
+ APFloat::rmNearestTiesToEven, &ignored);
return ConstantFP::get(Val);
}
return 0; // Can't fold.
@@ -227,10 +228,11 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
case Instruction::FPToSI:
if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V)) {
const APFloat &V = FPC->getValueAPF();
+ bool ignored;
uint64_t x[2];
uint32_t DestBitWidth = cast<IntegerType>(DestTy)->getBitWidth();
(void) V.convertToInteger(x, DestBitWidth, opc==Instruction::FPToSI,
- APFloat::rmTowardZero);
+ APFloat::rmTowardZero, &ignored);
APInt Val(DestBitWidth, 2, x);
return ConstantInt::get(Val);
}
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 4471cfd..b0dd163 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -373,7 +373,8 @@ ConstantFP *ConstantFP::get(const APFloat &V) {
/// 2.0/1.0 etc, that are known-valid both as double and as the target format.
ConstantFP *ConstantFP::get(const Type *Ty, double V) {
APFloat FV(V);
- FV.convert(*TypeToFloatSemantics(Ty), APFloat::rmNearestTiesToEven);
+ bool ignored;
+ FV.convert(*TypeToFloatSemantics(Ty), APFloat::rmNearestTiesToEven, &ignored);
return get(FV);
}
@@ -955,20 +956,25 @@ bool ConstantInt::isValueValidForType(const Type *Ty, int64_t Val) {
bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) {
// convert modifies in place, so make a copy.
APFloat Val2 = APFloat(Val);
+ bool losesInfo;
switch (Ty->getTypeID()) {
default:
return false; // These can't be represented as floating point!
// 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::FloatTyID: {
+ if (&Val2.getSemantics() == &APFloat::IEEEsingle)
+ return true;
+ Val2.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, &losesInfo);
+ return !losesInfo;
+ }
+ case Type::DoubleTyID: {
+ if (&Val2.getSemantics() == &APFloat::IEEEsingle ||
+ &Val2.getSemantics() == &APFloat::IEEEdouble)
+ return true;
+ Val2.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &losesInfo);
+ return !losesInfo;
+ }
case Type::X86_FP80TyID:
return &Val2.getSemantics() == &APFloat::IEEEsingle ||
&Val2.getSemantics() == &APFloat::IEEEdouble ||
diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp
index a802373..afc1c90 100644
--- a/lib/VMCore/Core.cpp
+++ b/lib/VMCore/Core.cpp
@@ -302,7 +302,9 @@ static const fltSemantics &SemanticsForType(Type *Ty) {
LLVMValueRef LLVMConstReal(LLVMTypeRef RealTy, double N) {
APFloat APN(N);
- APN.convert(SemanticsForType(unwrap(RealTy)), APFloat::rmNearestTiesToEven);
+ bool ignored;
+ APN.convert(SemanticsForType(unwrap(RealTy)), APFloat::rmNearestTiesToEven,
+ &ignored);
return wrap(ConstantFP::get(APN));
}