diff options
-rw-r--r-- | include/llvm/ADT/APFloat.h | 6 | ||||
-rw-r--r-- | include/llvm/CodeGen/SelectionDAGNodes.h | 3 | ||||
-rw-r--r-- | lib/AsmParser/llvmAsmParser.y | 14 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/FastISel.cpp | 12 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 23 | ||||
-rw-r--r-- | lib/ExecutionEngine/ExecutionEngine.cpp | 3 | ||||
-rw-r--r-- | lib/Support/APFloat.cpp | 51 | ||||
-rw-r--r-- | lib/Target/CBackend/CBackend.cpp | 3 | ||||
-rw-r--r-- | lib/Target/CppBackend/CPPBackend.cpp | 3 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 7 | ||||
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 4 | ||||
-rw-r--r-- | lib/VMCore/ConstantFold.cpp | 6 | ||||
-rw-r--r-- | lib/VMCore/Constants.cpp | 26 | ||||
-rw-r--r-- | lib/VMCore/Core.cpp | 4 |
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)); } |