[llvm-commits] [llvm] r57329 - in /llvm/trunk: include/llvm/ADT/ include/llvm/CodeGen/ lib/AsmParser/ lib/CodeGen/AsmPrinter/ lib/CodeGen/SelectionDAG/ lib/ExecutionEngine/ lib/Support/ lib/Target/CBackend/ lib/Target/CppBackend/ lib/Target/X86/ lib/Transforms/Scalar/ lib/VMCore/
Dale Johannesen
dalej at apple.com
Thu Oct 9 16:00:40 PDT 2008
Author: johannes
Date: Thu Oct 9 18:00:39 2008
New Revision: 57329
URL: http://llvm.org/viewvc/llvm-project?rev=57329&view=rev
Log:
Add a "loses information" return value to APFloat::convert
and APFloat::convertToInteger. Restore return value to
IEEE754. Adjust all users accordingly.
Modified:
llvm/trunk/include/llvm/ADT/APFloat.h
llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
llvm/trunk/lib/AsmParser/llvmAsmParser.y
llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
llvm/trunk/lib/Support/APFloat.cpp
llvm/trunk/lib/Target/CBackend/CBackend.cpp
llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
llvm/trunk/lib/VMCore/ConstantFold.cpp
llvm/trunk/lib/VMCore/Constants.cpp
llvm/trunk/lib/VMCore/Core.cpp
Modified: llvm/trunk/include/llvm/ADT/APFloat.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=57329&r1=57328&r2=57329&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/APFloat.h (original)
+++ llvm/trunk/include/llvm/ADT/APFloat.h Thu Oct 9 18:00:39 2008
@@ -216,9 +216,9 @@
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 @@
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);
Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=57329&r1=57328&r2=57329&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Thu Oct 9 18:00:39 2008
@@ -1756,12 +1756,13 @@
/// 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;
Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.y?rev=57329&r1=57328&r2=57329&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/llvmAsmParser.y (original)
+++ llvm/trunk/lib/AsmParser/llvmAsmParser.y Thu Oct 9 18:00:39 2008
@@ -428,8 +428,11 @@
// 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 @@
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
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=57329&r1=57328&r2=57329&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Thu Oct 9 18:00:39 2008
@@ -1000,8 +1000,11 @@
// 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()
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=57329&r1=57328&r2=57329&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Thu Oct 9 18:00:39 2008
@@ -93,8 +93,10 @@
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 @@
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);
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=57329&r1=57328&r2=57329&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Oct 9 18:00:39 2008
@@ -84,8 +84,10 @@
// 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 @@
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 @@
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 @@
OS << '<' << CSDN->getValueAPF().convertToDouble() << '>';
else {
OS << "<APFloat(";
- CSDN->getValueAPF().convertToAPInt().dump();
+ CSDN->getValueAPF().bitcastToAPInt().dump();
OS << ")>";
}
} else if (const GlobalAddressSDNode *GADN =
Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp?rev=57329&r1=57328&r2=57329&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp Thu Oct 9 18:00:39 2008
@@ -498,9 +498,10 @@
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;
Modified: llvm/trunk/lib/Support/APFloat.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=57329&r1=57328&r2=57329&view=diff
==============================================================================
--- llvm/trunk/lib/Support/APFloat.cpp (original)
+++ llvm/trunk/lib/Support/APFloat.cpp Thu Oct 9 18:00:39 2008
@@ -788,6 +788,7 @@
integerPart scratch[4];
integerPart *fullSignificand;
lostFraction lost_fraction;
+ bool ignored;
assert(semantics == rhs.semantics);
@@ -836,7 +837,7 @@
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 @@
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 @@
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 @@
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::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 @@
assertArithmeticOK(*semantics);
+ *isExact = false;
+
/* Handle the three special cases first. */
if(category == fcInfinity || category == fcNaN)
return opInvalidOp;
@@ -1785,7 +1800,8 @@
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 @@
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;
Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=57329&r1=57328&r2=57329&view=diff
==============================================================================
--- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original)
+++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Thu Oct 9 18:00:39 2008
@@ -832,12 +832,13 @@
// 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());
Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=57329&r1=57328&r2=57329&view=diff
==============================================================================
--- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original)
+++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Thu Oct 9 18:00:39 2008
@@ -218,9 +218,10 @@
// 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
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=57329&r1=57328&r2=57329&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Oct 9 18:00:39 2008
@@ -482,13 +482,16 @@
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
Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=57329&r1=57328&r2=57329&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Thu Oct 9 18:00:39 2008
@@ -7856,8 +7856,10 @@
/// 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;
}
Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=57329&r1=57328&r2=57329&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/ConstantFold.cpp (original)
+++ llvm/trunk/lib/VMCore/ConstantFold.cpp Thu Oct 9 18:00:39 2008
@@ -213,13 +213,14 @@
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 @@
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);
}
Modified: llvm/trunk/lib/VMCore/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=57329&r1=57328&r2=57329&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Constants.cpp (original)
+++ llvm/trunk/lib/VMCore/Constants.cpp Thu Oct 9 18:00:39 2008
@@ -373,7 +373,8 @@
/// 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 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 ||
Modified: llvm/trunk/lib/VMCore/Core.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Core.cpp?rev=57329&r1=57328&r2=57329&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Core.cpp (original)
+++ llvm/trunk/lib/VMCore/Core.cpp Thu Oct 9 18:00:39 2008
@@ -302,7 +302,9 @@
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));
}
More information about the llvm-commits
mailing list