================
@@ -1536,97 +1536,55 @@ static void writeOptimizationInfo(raw_ostream &Out,
const User *U) {
}
}
-static void writeAPFloatInternal(raw_ostream &Out, const APFloat &APF) {
- 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 = &APF.getSemantics() == &APFloat::IEEEdouble();
- bool isInf = APF.isInfinity();
- bool isNaN = APF.isNaN();
-
- if (!isInf && !isNaN) {
- double Val = APF.convertToDouble();
- SmallString<128> StrVal;
- 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.
- //
- assert((isDigit(StrVal[0]) ||
- ((StrVal[0] == '-' || StrVal[0] == '+') && isDigit(StrVal[1])))
&&
- "[-+]?[0-9] regex does not match!");
- // Reparse stringized version!
- if (APFloat(APFloat::IEEEdouble(), StrVal).convertToDouble() == Val) {
- Out << StrVal;
- return;
- }
- }
+static void WriteFullHexAPInt(raw_ostream &Out, const APInt &Val) {
+ SmallVector<char, 32> Bits;
+ Val.toStringUnsigned(Bits, 16);
+ unsigned NumDigits = std::max((Val.getBitWidth() + 3) / 4, 1U);
+ Out << "0x";
+ for (unsigned i = 0; i < NumDigits - Bits.size(); i++)
+ Out << "0";
+ Out << Bits;
+}
- // Otherwise we could not reparse it to exactly the same value, so we must
- // output the string in hexadecimal format! Note that loading and storing
- // floating point types changes the bits of NaNs on some hosts, notably
- // x86, so we must not use these types.
- static_assert(sizeof(double) == sizeof(uint64_t),
- "assuming that double is 64 bits!");
- APFloat apf = APF;
-
- // Floats are represented in ASCII IR as double, convert.
- // FIXME: We should allow 32-bit hex float and remove this.
- if (!isDouble) {
- // A signaling NaN is quieted on conversion, so we need to recreate the
- // expected value after convert (quiet bit of the payload is clear).
- bool IsSNAN = apf.isSignaling();
- apf.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
- &ignored);
- if (IsSNAN) {
- APInt Payload = apf.bitcastToAPInt();
- apf =
- APFloat::getSNaN(APFloat::IEEEdouble(), apf.isNegative(),
&Payload);
- }
+static void writeAPFloatInternal(raw_ostream &Out, const APFloat &APF) {
+ // Check for special values in APFloat.
+ if (APF.isInfinity()) {
+ Out << (APF.isNegative() ? "-" : "+") << "inf";
+ return;
+ } else if (APF.isNaN()) {
+ Out << (APF.isNegative() ? "-" : "+");
+ APInt Payload = APF.getNaNPayload();
+ // The quiet bit of a NaN is the highest bit of the payload, so the
+ // preferred QNaN value happens to be the sign mask value.
+ if (Payload.isSignMask()) {
+ Out << "qnan";
+ } else {
+ if (APF.isSignaling())
+ Out << "s";
+ Out << "nan(";
+ // Clear out the signaling/quiet bit of the payload for output.
+ Payload.clearBit(Payload.getBitWidth() - 1);
+ // Trim the string to exclude leading 0's.
+ WriteFullHexAPInt(Out, Payload.trunc(Payload.getActiveBits()));
+ Out << ")";
}
+ return;
+ }
- Out << format_hex(apf.bitcastToAPInt().getZExtValue(), 0, /*Upper=*/true);
+ // Try for a decimal string output. If the value is convertible back to the
+ // same APFloat value, then we know that it is safe to use it. Otherwise,
fall
+ // back onto the hexadecimal format.
+ SmallString<128> StrVal;
+ APF.toString(StrVal, 6, 0, false);
----------------
jcranmer-intel wrote:
Possibly, but we don't actually compute that information anywhere for
`fltSemantics`.
https://github.com/llvm/llvm-project/pull/190649
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits