summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/IR/AsmWriter.cpp45
-rw-r--r--llvm/lib/Support/APFloat.cpp31
2 files changed, 45 insertions, 31 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index d0b77e7218b..27f6e366876 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1103,35 +1103,34 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
}
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
- if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEsingle() ||
- &CFP->getValueAPF().getSemantics() == &APFloat::IEEEdouble()) {
+ const APFloat &APF = CFP->getValueAPF();
+ if (&APF.getSemantics() == &APFloat::IEEEsingle() ||
+ &APF.getSemantics() == &APFloat::IEEEdouble()) {
// We would like to output the FP constant value in exponential notation,
// but we cannot do this if doing so will lose precision. Check here to
// make sure that we only output it in exponential format if we can parse
// the value back and get the same value.
//
bool ignored;
- bool isDouble = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEdouble();
- bool isInf = CFP->getValueAPF().isInfinity();
- bool isNaN = CFP->getValueAPF().isNaN();
+ bool isDouble = &APF.getSemantics() == &APFloat::IEEEdouble();
+ bool isInf = APF.isInfinity();
+ bool isNaN = APF.isNaN();
if (!isInf && !isNaN) {
- double Val = isDouble ? CFP->getValueAPF().convertToDouble() :
- CFP->getValueAPF().convertToFloat();
+ double Val = isDouble ? APF.convertToDouble() : APF.convertToFloat();
SmallString<128> StrVal;
- raw_svector_ostream(StrVal) << Val;
-
+ APF.toString(StrVal, 6, 0, false);
// Check to make sure that the stringized number is not some string like
// "Inf" or NaN, that atof will accept, but the lexer will not. Check
// that the string matches the "[-+]?[0-9]" regex.
//
- if ((StrVal[0] >= '0' && StrVal[0] <= '9') ||
- ((StrVal[0] == '-' || StrVal[0] == '+') &&
- (StrVal[1] >= '0' && StrVal[1] <= '9'))) {
- // Reparse stringized version!
- if (APFloat(APFloat::IEEEdouble(), StrVal).convertToDouble() == Val) {
- Out << StrVal;
- return;
- }
+ assert((StrVal[0] >= '0' && StrVal[0] <= '9') ||
+ ((StrVal[0] == '-' || StrVal[0] == '+') &&
+ (StrVal[1] >= '0' && StrVal[1] <= '9')) &&
+ "[-+]?[0-9] regex does not match!");
+ // Reparse stringized version!
+ if (APFloat(APFloat::IEEEdouble(), StrVal).convertToDouble() == Val) {
+ Out << StrVal;
+ return;
}
}
// Otherwise we could not reparse it to exactly the same value, so we must
@@ -1140,7 +1139,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
// x86, so we must not use these types.
static_assert(sizeof(double) == sizeof(uint64_t),
"assuming that double is 64 bits!");
- APFloat apf = CFP->getValueAPF();
+ APFloat apf = APF;
// Floats are represented in ASCII IR as double, convert.
if (!isDouble)
apf.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
@@ -1153,27 +1152,27 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
// These appear as a magic letter identifying the type, then a
// fixed number of hex digits.
Out << "0x";
- APInt API = CFP->getValueAPF().bitcastToAPInt();
- if (&CFP->getValueAPF().getSemantics() == &APFloat::x87DoubleExtended()) {
+ APInt API = APF.bitcastToAPInt();
+ if (&APF.getSemantics() == &APFloat::x87DoubleExtended()) {
Out << 'K';
Out << format_hex_no_prefix(API.getHiBits(16).getZExtValue(), 4,
/*Upper=*/true);
Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
/*Upper=*/true);
return;
- } else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad()) {
+ } else if (&APF.getSemantics() == &APFloat::IEEEquad()) {
Out << 'L';
Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
/*Upper=*/true);
Out << format_hex_no_prefix(API.getHiBits(64).getZExtValue(), 16,
/*Upper=*/true);
- } else if (&CFP->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble()) {
+ } else if (&APF.getSemantics() == &APFloat::PPCDoubleDouble()) {
Out << 'M';
Out << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
/*Upper=*/true);
Out << format_hex_no_prefix(API.getHiBits(64).getZExtValue(), 16,
/*Upper=*/true);
- } else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEhalf()) {
+ } else if (&APF.getSemantics() == &APFloat::IEEEhalf()) {
Out << 'H';
Out << format_hex_no_prefix(API.getZExtValue(), 4,
/*Upper=*/true);
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp
index c4c892f0352..e1e2c22e1df 100644
--- a/llvm/lib/Support/APFloat.cpp
+++ b/llvm/lib/Support/APFloat.cpp
@@ -3393,7 +3393,7 @@ namespace {
}
void IEEEFloat::toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision,
- unsigned FormatMaxPadding) const {
+ unsigned FormatMaxPadding, bool TruncateZero) const {
switch (category) {
case fcInfinity:
if (isNegative())
@@ -3407,9 +3407,16 @@ void IEEEFloat::toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision,
if (isNegative())
Str.push_back('-');
- if (!FormatMaxPadding)
- append(Str, "0.0E+0");
- else
+ if (!FormatMaxPadding) {
+ if (TruncateZero)
+ append(Str, "0.0E+0");
+ else {
+ append(Str, "0.0");
+ if (FormatPrecision > 1)
+ Str.append(FormatPrecision - 1, '0');
+ append(Str, "e+00");
+ }
+ } else
Str.push_back('0');
return;
@@ -3543,12 +3550,16 @@ void IEEEFloat::toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision,
Str.push_back(buffer[NDigits-1]);
Str.push_back('.');
- if (NDigits == 1)
+ if (NDigits == 1 && TruncateZero)
Str.push_back('0');
else
for (unsigned I = 1; I != NDigits; ++I)
Str.push_back(buffer[NDigits-1-I]);
- Str.push_back('E');
+ // Fill with zeros up to FormatPrecision.
+ if (!TruncateZero && FormatPrecision > NDigits - 1)
+ Str.append(FormatPrecision - NDigits + 1, '0');
+ // For !TruncateZero we use lower 'e'.
+ Str.push_back(TruncateZero ? 'E' : 'e');
Str.push_back(exp >= 0 ? '+' : '-');
if (exp < 0) exp = -exp;
@@ -3557,6 +3568,9 @@ void IEEEFloat::toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision,
expbuf.push_back((char) ('0' + (exp % 10)));
exp /= 10;
} while (exp);
+ // Exponent always at least two digits if we do not truncate zeros.
+ if (!TruncateZero && expbuf.size() < 2)
+ expbuf.push_back('0');
for (unsigned I = 0, E = expbuf.size(); I != E; ++I)
Str.push_back(expbuf[E-1-I]);
return;
@@ -4362,10 +4376,11 @@ bool DoubleAPFloat::isInteger() const {
void DoubleAPFloat::toString(SmallVectorImpl<char> &Str,
unsigned FormatPrecision,
- unsigned FormatMaxPadding) const {
+ unsigned FormatMaxPadding,
+ bool TruncateZero) const {
assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt())
- .toString(Str, FormatPrecision, FormatMaxPadding);
+ .toString(Str, FormatPrecision, FormatMaxPadding, TruncateZero);
}
bool DoubleAPFloat::getExactInverse(APFloat *inv) const {
OpenPOWER on IntegriCloud