Do not use host floating point types when emitting
ASCII IR; loading and storing these can change the
bits of NaNs on some hosts.  Remove or add warnings
at a few other places using host floating point;
this is a bad thing to do in general.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62712 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index c296770..d8d414d 100644
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -599,7 +599,8 @@
 }
 
 /* Make this number a NaN, with an arbitrary but deterministic value
-   for the significand.  */
+   for the significand.  If double or longer, this is a signalling NaN,
+   which may not be ideal. */
 void
 APFloat::makeNaN(void)
 {
diff --git a/lib/Support/FoldingSet.cpp b/lib/Support/FoldingSet.cpp
index d2b02f2..3a1a0cd 100644
--- a/lib/Support/FoldingSet.cpp
+++ b/lib/Support/FoldingSet.cpp
@@ -61,12 +61,6 @@
   if ((uint64_t)(int)I != I)
     Bits.push_back(unsigned(I >> 32));
 }
-void FoldingSetNodeID::AddFloat(float F) {
-  Bits.push_back(FloatToBits(F));
-}
-void FoldingSetNodeID::AddDouble(double D) {
- AddInteger(DoubleToBits(D));
-}
 
 void FoldingSetNodeID::AddString(const char *String) {
   unsigned Size = static_cast<unsigned>(strlen(String));
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index b59ec08..6a17516 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -640,6 +640,7 @@
       // 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;
       double Val = isDouble ? CFP->getValueAPF().convertToDouble() :
                               CFP->getValueAPF().convertToFloat();
@@ -659,11 +660,20 @@
         }
       }
       // Otherwise we could not reparse it to exactly the same value, so we must
-      // output the string in hexadecimal format!
+      // 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.
       assert(sizeof(double) == sizeof(uint64_t) &&
              "assuming that double is 64 bits!");
       char Buffer[40];
-      Out << "0x" << utohex_buffer(uint64_t(DoubleToBits(Val)), Buffer+40);
+      APFloat apf = CFP->getValueAPF();
+      // Floats are represented in ASCII IR as double, convert.
+      if (!isDouble)
+        apf.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, 
+                          &ignored);
+      Out << "0x" << 
+              utohex_buffer(uint64_t(apf.bitcastToAPInt().getZExtValue()), 
+                            Buffer+40);
       return;
     }