[APFloat] Make functions that produce APFloaat objects use correct semantics.

Summary:
Fixes PR30869.

In D25977 I meant to change all functions that care about lifetime. I
changed constructors, factory functions, but I missed member/free
functions that return new instances. This patch changes them.

Reviewers: hfinkel, kbarton, echristo, joerg

Subscribers: llvm-commits, mehdi_amini

Differential Revision: https://reviews.llvm.org/D26269

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@286060 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tim Shen
2016-11-06 07:38:37 +00:00
parent e7c8559144
commit c7524ad33d
3 changed files with 84 additions and 45 deletions
+37 -19
View File
@@ -3238,23 +3238,6 @@ void IEEEFloat::initFromAPInt(const fltSemantics *Sem, const APInt &api) {
llvm_unreachable(nullptr);
}
IEEEFloat IEEEFloat::getAllOnesValue(unsigned BitWidth) {
switch (BitWidth) {
case 16:
return IEEEFloat(IEEEhalf, APInt::getAllOnesValue(BitWidth));
case 32:
return IEEEFloat(IEEEsingle, APInt::getAllOnesValue(BitWidth));
case 64:
return IEEEFloat(IEEEdouble, APInt::getAllOnesValue(BitWidth));
case 80:
return IEEEFloat(x87DoubleExtended, APInt::getAllOnesValue(BitWidth));
case 128:
return IEEEFloat(IEEEquad, APInt::getAllOnesValue(BitWidth));
default:
llvm_unreachable("Unknown floating bit width");
}
}
/// Make this number the largest magnitude normal number in the given
/// semantics.
void IEEEFloat::makeLargest(bool Negative) {
@@ -3902,6 +3885,18 @@ DoubleAPFloat &DoubleAPFloat::operator=(const DoubleAPFloat &RHS) {
} // End detail namespace
APFloat::Storage::Storage(IEEEFloat F, const fltSemantics &Semantics) {
if (usesLayout<IEEEFloat>(Semantics)) {
new (&IEEE) IEEEFloat(std::move(F));
} else if (usesLayout<DoubleAPFloat>(Semantics)) {
new (&Double)
DoubleAPFloat(Semantics, APFloat(std::move(F), F.getSemantics()),
APFloat(IEEEdouble));
} else {
llvm_unreachable("Unexpected semantics");
}
}
APFloat::opStatus APFloat::convertFromString(StringRef Str, roundingMode RM) {
return getIEEE().convertFromString(Str, RM);
}
@@ -3925,16 +3920,39 @@ APFloat::opStatus APFloat::convert(const fltSemantics &ToSemantics,
assert(&ToSemantics == &PPCDoubleDouble);
auto Ret = U.IEEE.convert(PPCDoubleDoubleImpl, RM, losesInfo);
*this = APFloat(
DoubleAPFloat(PPCDoubleDouble, std::move(*this), APFloat(IEEEdouble)));
DoubleAPFloat(PPCDoubleDouble, std::move(*this), APFloat(IEEEdouble)),
ToSemantics);
return Ret;
} else if (usesLayout<DoubleAPFloat>(getSemantics()) &&
usesLayout<IEEEFloat>(ToSemantics)) {
auto Ret = getIEEE().convert(ToSemantics, RM, losesInfo);
*this = APFloat(std::move(getIEEE()));
*this = APFloat(std::move(getIEEE()), ToSemantics);
return Ret;
} else {
llvm_unreachable("Unexpected semantics");
}
}
APFloat APFloat::getAllOnesValue(unsigned BitWidth, bool isIEEE) {
if (isIEEE) {
switch (BitWidth) {
case 16:
return APFloat(IEEEhalf, APInt::getAllOnesValue(BitWidth));
case 32:
return APFloat(IEEEsingle, APInt::getAllOnesValue(BitWidth));
case 64:
return APFloat(IEEEdouble, APInt::getAllOnesValue(BitWidth));
case 80:
return APFloat(x87DoubleExtended, APInt::getAllOnesValue(BitWidth));
case 128:
return APFloat(IEEEquad, APInt::getAllOnesValue(BitWidth));
default:
llvm_unreachable("Unknown floating bit width");
}
} else {
assert(BitWidth == 128);
return APFloat(PPCDoubleDouble, APInt::getAllOnesValue(BitWidth));
}
}
} // End llvm namespace