mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-31 10:34:17 +00:00
Add a "loses information" return value to APFloat::convert
and APFloat::convertToInteger. Restore return value to IEEE754. Adjust all users accordingly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@57329 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7111b02c73
commit
23a98551ab
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 =
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 ||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user