================
@@ -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);
----------------
efriedma-quic wrote:

Oh, so it's just inherited, and nobody ever really thought about it.

Would it make sense to just print the minimum number of digits required to 
round-trip, like `std::to_chars()`?

https://github.com/llvm/llvm-project/pull/190649
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to