Culling out use of unions for converting FP to bits and vice versa.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22838 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 3606c43..eb634a6 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -25,6 +25,7 @@
 #include "llvm/ADT/GraphTraits.h"
 #include "llvm/ADT/iterator"
 #include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
 #include <cassert>
 #include <vector>
 
@@ -742,17 +743,7 @@
   /// As such, this method can be used to do an exact bit-for-bit comparison of
   /// two floating point values.
   bool isExactlyValue(double V) const {
-    union {
-      double V;
-      uint64_t I;
-    } T1;
-    T1.V = Value;
-    union {
-      double V;
-      uint64_t I;
-    } T2;
-    T2.V = V;
-    return T1.I == T2.I;
+    return DoubleToBits(V) == DoubleToBits(Value);
   }
 
   static bool classof(const ConstantFPSDNode *) { return true; }
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
index 91e82cc..1a9d87d 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/Constants.h
@@ -23,6 +23,7 @@
 #include "llvm/Constant.h"
 #include "llvm/Type.h"
 #include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
 
 namespace llvm {
 
@@ -277,12 +278,7 @@
   /// getNullValue.  Don't depend on == for doubles to tell us it's zero, it
   /// considers -0.0 to be null as well as 0.0.  :(
   virtual bool isNullValue() const {
-    union {
-      double V;
-      uint64_t I;
-    } T;
-    T.V = Val;
-    return T.I == 0;
+    return DoubleToBits(Val) == 0;
   }
 
   /// isExactlyValue - We don't rely on operator== working on double values, as
@@ -290,17 +286,7 @@
   /// As such, this method can be used to do an exact bit-for-bit comparison of
   /// two floating point values.
   bool isExactlyValue(double V) const {
-    union {
-      double V;
-      uint64_t I;
-    } T1;
-    T1.V = Val;
-    union {
-      double V;
-      uint64_t I;
-    } T2;
-    T2.V = V;
-    return T1.I == T2.I;
+    return DoubleToBits(V) == DoubleToBits(Val);
   }
 
   /// Methods for support type inquiry through isa, cast, and dyn_cast:
diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp
index f56c59a..6bb06c3 100644
--- a/lib/Bytecode/Reader/Reader.cpp
+++ b/lib/Bytecode/Reader/Reader.cpp
@@ -27,6 +27,7 @@
 #include "llvm/Config/alloca.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
 #include "llvm/Support/Compressor.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include <sstream>
 #include <algorithm>
@@ -162,29 +163,19 @@
 inline void BytecodeReader::read_float(float& FloatVal) {
   /// FIXME: This isn't optimal, it has size problems on some platforms
   /// where FP is not IEEE.
-  union {
-    float f;
-    uint32_t i;
-  } FloatUnion;
-  FloatUnion.i = At[0] | (At[1] << 8) | (At[2] << 16) | (At[3] << 24);
+  FloatVal = BitsToFloat(At[0] | (At[1] << 8) | (At[2] << 16) | (At[3] << 24));
   At+=sizeof(uint32_t);
-  FloatVal = FloatUnion.f;
 }
 
 /// Read a double value in little-endian order
 inline void BytecodeReader::read_double(double& DoubleVal) {
   /// FIXME: This isn't optimal, it has size problems on some platforms
   /// where FP is not IEEE.
-  union {
-    double d;
-    uint64_t i;
-  } DoubleUnion;
-  DoubleUnion.i = (uint64_t(At[0]) <<  0) | (uint64_t(At[1]) << 8) |
-                  (uint64_t(At[2]) << 16) | (uint64_t(At[3]) << 24) |
-                  (uint64_t(At[4]) << 32) | (uint64_t(At[5]) << 40) |
-                  (uint64_t(At[6]) << 48) | (uint64_t(At[7]) << 56);
+  DoubleVal = BitsToDouble((uint64_t(At[0]) <<  0) | (uint64_t(At[1]) << 8) |
+                           (uint64_t(At[2]) << 16) | (uint64_t(At[3]) << 24) |
+                           (uint64_t(At[4]) << 32) | (uint64_t(At[5]) << 40) |
+                           (uint64_t(At[6]) << 48) | (uint64_t(At[7]) << 56));
   At+=sizeof(uint64_t);
-  DoubleVal = DoubleUnion.d;
 }
 
 /// Read a block header and obtain its type and size
diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp
index 95bbd2e..b1f2634 100644
--- a/lib/Bytecode/Writer/Writer.cpp
+++ b/lib/Bytecode/Writer/Writer.cpp
@@ -27,6 +27,7 @@
 #include "llvm/SymbolTable.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
 #include "llvm/Support/Compressor.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/Statistic.h"
 #include <cstring>
@@ -139,33 +140,25 @@
 inline void BytecodeWriter::output_float(float& FloatVal) {
   /// FIXME: This isn't optimal, it has size problems on some platforms
   /// where FP is not IEEE.
-  union {
-    float f;
-    uint32_t i;
-  } FloatUnion;
-  FloatUnion.f = FloatVal;
-  Out.push_back( static_cast<unsigned char>( (FloatUnion.i & 0xFF )));
-  Out.push_back( static_cast<unsigned char>( (FloatUnion.i >> 8) & 0xFF));
-  Out.push_back( static_cast<unsigned char>( (FloatUnion.i >> 16) & 0xFF));
-  Out.push_back( static_cast<unsigned char>( (FloatUnion.i >> 24) & 0xFF));
+  uint32_t i = FloatToBits(FloatVal);
+  Out.push_back( static_cast<unsigned char>( (i & 0xFF )));
+  Out.push_back( static_cast<unsigned char>( (i >> 8) & 0xFF));
+  Out.push_back( static_cast<unsigned char>( (i >> 16) & 0xFF));
+  Out.push_back( static_cast<unsigned char>( (i >> 24) & 0xFF));
 }
 
 inline void BytecodeWriter::output_double(double& DoubleVal) {
   /// FIXME: This isn't optimal, it has size problems on some platforms
   /// where FP is not IEEE.
-  union {
-    double d;
-    uint64_t i;
-  } DoubleUnion;
-  DoubleUnion.d = DoubleVal;
-  Out.push_back( static_cast<unsigned char>( (DoubleUnion.i & 0xFF )));
-  Out.push_back( static_cast<unsigned char>( (DoubleUnion.i >> 8) & 0xFF));
-  Out.push_back( static_cast<unsigned char>( (DoubleUnion.i >> 16) & 0xFF));
-  Out.push_back( static_cast<unsigned char>( (DoubleUnion.i >> 24) & 0xFF));
-  Out.push_back( static_cast<unsigned char>( (DoubleUnion.i >> 32) & 0xFF));
-  Out.push_back( static_cast<unsigned char>( (DoubleUnion.i >> 40) & 0xFF));
-  Out.push_back( static_cast<unsigned char>( (DoubleUnion.i >> 48) & 0xFF));
-  Out.push_back( static_cast<unsigned char>( (DoubleUnion.i >> 56) & 0xFF));
+  uint64_t i = DoubleToBits(DoubleVal);
+  Out.push_back( static_cast<unsigned char>( (i & 0xFF )));
+  Out.push_back( static_cast<unsigned char>( (i >> 8) & 0xFF));
+  Out.push_back( static_cast<unsigned char>( (i >> 16) & 0xFF));
+  Out.push_back( static_cast<unsigned char>( (i >> 24) & 0xFF));
+  Out.push_back( static_cast<unsigned char>( (i >> 32) & 0xFF));
+  Out.push_back( static_cast<unsigned char>( (i >> 40) & 0xFF));
+  Out.push_back( static_cast<unsigned char>( (i >> 48) & 0xFF));
+  Out.push_back( static_cast<unsigned char>( (i >> 56) & 0xFF));
 }
 
 inline BytecodeBlock::BytecodeBlock(unsigned ID, BytecodeWriter& w,
diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp
index 497e9c8..d907d67 100644
--- a/lib/CodeGen/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter.cpp
@@ -15,6 +15,7 @@
 #include "llvm/Constants.h"
 #include "llvm/Instruction.h"
 #include "llvm/Support/Mangler.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Target/TargetMachine.h"
 using namespace llvm;
 
@@ -222,39 +223,27 @@
     // precision...
     double Val = CFP->getValue();
     if (CFP->getType() == Type::DoubleTy) {
-      union DU {                            // Abide by C TBAA rules
-        double FVal;
-        uint64_t UVal;
-      } U;
-      U.FVal = Val;
-
       if (Data64bitsDirective)
-        O << Data64bitsDirective << U.UVal << "\t" << CommentString
+        O << Data64bitsDirective << DoubleToBits(Val) << "\t" << CommentString
           << " double value: " << Val << "\n";
       else if (TD.isBigEndian()) {
-        O << Data32bitsDirective << unsigned(U.UVal >> 32)
+        O << Data32bitsDirective << unsigned(DoubleToBits(Val) >> 32)
           << "\t" << CommentString << " double most significant word "
           << Val << "\n";
-        O << Data32bitsDirective << unsigned(U.UVal)
+        O << Data32bitsDirective << unsigned(DoubleToBits(Val))
           << "\t" << CommentString << " double least significant word "
           << Val << "\n";
       } else {
-        O << Data32bitsDirective << unsigned(U.UVal)
+        O << Data32bitsDirective << unsigned(DoubleToBits(Val))
           << "\t" << CommentString << " double least significant word " << Val
           << "\n";
-        O << Data32bitsDirective << unsigned(U.UVal >> 32)
+        O << Data32bitsDirective << unsigned(DoubleToBits(Val) >> 32)
           << "\t" << CommentString << " double most significant word " << Val
           << "\n";
       }
       return;
     } else {
-      union FU {                            // Abide by C TBAA rules
-        float FVal;
-        int32_t UVal;
-      } U;
-      U.FVal = (float)Val;
-
-      O << Data32bitsDirective << U.UVal << "\t" << CommentString
+      O << Data32bitsDirective << FloatToBits(Val) << "\t" << CommentString
         << " float " << Val << "\n";
       return;
     }
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index ab07030..2c01982 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -975,23 +975,17 @@
     // Turn 'store float 1.0, Ptr' -> 'store int 0x12345678, Ptr'
     if (ConstantFPSDNode *CFP =dyn_cast<ConstantFPSDNode>(Node->getOperand(1))){
       if (CFP->getValueType(0) == MVT::f32) {
-        union {
-          unsigned I;
-          float    F;
-        } V;
-        V.F = CFP->getValue();
         Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1,
-                             DAG.getConstant(V.I, MVT::i32), Tmp2,
+                             DAG.getConstant(FloatToBits(CFP->getValue()),
+                                             MVT::i32),
+                             Tmp2,
                              Node->getOperand(3));
       } else {
         assert(CFP->getValueType(0) == MVT::f64 && "Unknown FP type!");
-        union {
-          uint64_t I;
-          double   F;
-        } V;
-        V.F = CFP->getValue();
         Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1,
-                             DAG.getConstant(V.I, MVT::i64), Tmp2,
+                             DAG.getConstant(DoubleToBits(CFP->getValue()),
+                                             MVT::i64),
+                             Tmp2,
                              Node->getOperand(3));
       }
       Node = Result.Val;
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 6afa9d0..81b0803 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -224,12 +224,8 @@
                                          N->getValueType(0)));
     break;
   case ISD::ConstantFP: {
-    union {
-      double DV;
-      uint64_t IV;
-    };
-    DV = cast<ConstantFPSDNode>(N)->getValue();
-    ConstantFPs.erase(std::make_pair(IV, N->getValueType(0)));
+    uint64_t V = DoubleToBits(cast<ConstantFPSDNode>(N)->getValue());
+    ConstantFPs.erase(std::make_pair(V, N->getValueType(0)));
     break;
   }
   case ISD::CONDCODE:
@@ -385,14 +381,7 @@
   // Do the map lookup using the actual bit pattern for the floating point
   // value, so that we don't have problems with 0.0 comparing equal to -0.0, and
   // we don't have issues with SNANs.
-  union {
-    double DV;
-    uint64_t IV;
-  };
-
-  DV = Val;
-
-  SDNode *&N = ConstantFPs[std::make_pair(IV, VT)];
+  SDNode *&N = ConstantFPs[std::make_pair(DoubleToBits(Val), VT)];
   if (N) return SDOperand(N, 0);
   N = new ConstantFPSDNode(Val, VT);
   AllNodes.push_back(N);
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index b29187b..fc87afd 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -32,6 +32,7 @@
 #include "llvm/Support/GetElementPtrTypeIterator.h"
 #include "llvm/Support/InstVisitor.h"
 #include "llvm/Support/Mangler.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/MathExtras.h"
@@ -585,14 +586,10 @@
         const unsigned long SignalNaN = 0x7ff4UL;
 
         // We need to grab the first part of the FP #
-        union {
-          double   d;
-          uint64_t ll;
-        } DHex;
         char Buffer[100];
 
-        DHex.d = FPC->getValue();
-        sprintf(Buffer, "0x%llx", (unsigned long long)DHex.ll);
+        uint64_t ll = DoubleToBits(FPC->getValue());
+        sprintf(Buffer, "0x%llx", (unsigned long long)ll);
 
         std::string Num(&Buffer[0], &Buffer[6]);
         unsigned long Val = strtoul(Num.c_str(), 0, 16);
@@ -953,16 +950,6 @@
 
 /// Output all floating point constants that cannot be printed accurately...
 void CWriter::printFloatingPointConstants(Function &F) {
-  union {
-    double D;
-    uint64_t U;
-  } DBLUnion;
-
-  union {
-    float F;
-    unsigned U;
-  } FLTUnion;
-
   // Scan the module for floating point constants.  If any FP constant is used
   // in the function, we want to redirect it here so that we do not depend on
   // the precision of the printed form, unless the printed form preserves
@@ -979,14 +966,12 @@
         FPConstantMap[FPC] = FPCounter;  // Number the FP constants
 
         if (FPC->getType() == Type::DoubleTy) {
-          DBLUnion.D = Val;
           Out << "static const ConstantDoubleTy FPConstant" << FPCounter++
-              << " = 0x" << std::hex << DBLUnion.U << std::dec
+              << " = 0x" << std::hex << DoubleToBits(Val) << std::dec
               << "ULL;    /* " << Val << " */\n";
         } else if (FPC->getType() == Type::FloatTy) {
-          FLTUnion.F = Val;
           Out << "static const ConstantFloatTy FPConstant" << FPCounter++
-              << " = 0x" << std::hex << FLTUnion.U << std::dec
+              << " = 0x" << std::hex << FloatToBits(Val) << std::dec
               << "U;    /* " << Val << " */\n";
         } else
           assert(0 && "Unknown float type!");
diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp
index b29187b..fc87afd 100644
--- a/lib/Target/CBackend/Writer.cpp
+++ b/lib/Target/CBackend/Writer.cpp
@@ -32,6 +32,7 @@
 #include "llvm/Support/GetElementPtrTypeIterator.h"
 #include "llvm/Support/InstVisitor.h"
 #include "llvm/Support/Mangler.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/MathExtras.h"
@@ -585,14 +586,10 @@
         const unsigned long SignalNaN = 0x7ff4UL;
 
         // We need to grab the first part of the FP #
-        union {
-          double   d;
-          uint64_t ll;
-        } DHex;
         char Buffer[100];
 
-        DHex.d = FPC->getValue();
-        sprintf(Buffer, "0x%llx", (unsigned long long)DHex.ll);
+        uint64_t ll = DoubleToBits(FPC->getValue());
+        sprintf(Buffer, "0x%llx", (unsigned long long)ll);
 
         std::string Num(&Buffer[0], &Buffer[6]);
         unsigned long Val = strtoul(Num.c_str(), 0, 16);
@@ -953,16 +950,6 @@
 
 /// Output all floating point constants that cannot be printed accurately...
 void CWriter::printFloatingPointConstants(Function &F) {
-  union {
-    double D;
-    uint64_t U;
-  } DBLUnion;
-
-  union {
-    float F;
-    unsigned U;
-  } FLTUnion;
-
   // Scan the module for floating point constants.  If any FP constant is used
   // in the function, we want to redirect it here so that we do not depend on
   // the precision of the printed form, unless the printed form preserves
@@ -979,14 +966,12 @@
         FPConstantMap[FPC] = FPCounter;  // Number the FP constants
 
         if (FPC->getType() == Type::DoubleTy) {
-          DBLUnion.D = Val;
           Out << "static const ConstantDoubleTy FPConstant" << FPCounter++
-              << " = 0x" << std::hex << DBLUnion.U << std::dec
+              << " = 0x" << std::hex << DoubleToBits(Val) << std::dec
               << "ULL;    /* " << Val << " */\n";
         } else if (FPC->getType() == Type::FloatTy) {
-          FLTUnion.F = Val;
           Out << "static const ConstantFloatTy FPConstant" << FPCounter++
-              << " = 0x" << std::hex << FLTUnion.U << std::dec
+              << " = 0x" << std::hex << FloatToBits(Val) << std::dec
               << "U;    /* " << Val << " */\n";
         } else
           assert(0 && "Unknown float type!");
diff --git a/lib/Target/Sparc/SparcAsmPrinter.cpp b/lib/Target/Sparc/SparcAsmPrinter.cpp
index c8852cc..4e908a1 100644
--- a/lib/Target/Sparc/SparcAsmPrinter.cpp
+++ b/lib/Target/Sparc/SparcAsmPrinter.cpp
@@ -247,22 +247,12 @@
     switch (CFP->getType()->getTypeID()) {
     default: assert(0 && "Unknown floating point type!");
     case Type::FloatTyID: {
-      union FU {                            // Abide by C TBAA rules
-        float FVal;
-        unsigned UVal;
-      } U;
-      U.FVal = Val;
-      O << ".long\t" << U.UVal << "\t! float " << Val << "\n";
+      O << ".long\t" << FloatToBits(Val) << "\t! float " << Val << "\n";
       return;
     }
     case Type::DoubleTyID: {
-      union DU {                            // Abide by C TBAA rules
-        double FVal;
-        uint64_t UVal;
-      } U;
-      U.FVal = Val;
-      O << ".word\t0x" << std::hex << (U.UVal >> 32) << std::dec << "\t! double " << Val << "\n";
-      O << ".word\t0x" << std::hex << (U.UVal & 0xffffffffUL) << std::dec << "\t! double " << Val << "\n";
+      O << ".word\t0x" << std::hex << (DoubleToBits(Val) >> 32) << std::dec << "\t! double " << Val << "\n";
+      O << ".word\t0x" << std::hex << (DoubleToBits(Val) & 0xffffffffUL) << std::dec << "\t! double " << Val << "\n";
       return;
     }
     }
diff --git a/lib/Target/SparcV8/SparcV8AsmPrinter.cpp b/lib/Target/SparcV8/SparcV8AsmPrinter.cpp
index c8852cc..4e908a1 100644
--- a/lib/Target/SparcV8/SparcV8AsmPrinter.cpp
+++ b/lib/Target/SparcV8/SparcV8AsmPrinter.cpp
@@ -247,22 +247,12 @@
     switch (CFP->getType()->getTypeID()) {
     default: assert(0 && "Unknown floating point type!");
     case Type::FloatTyID: {
-      union FU {                            // Abide by C TBAA rules
-        float FVal;
-        unsigned UVal;
-      } U;
-      U.FVal = Val;
-      O << ".long\t" << U.UVal << "\t! float " << Val << "\n";
+      O << ".long\t" << FloatToBits(Val) << "\t! float " << Val << "\n";
       return;
     }
     case Type::DoubleTyID: {
-      union DU {                            // Abide by C TBAA rules
-        double FVal;
-        uint64_t UVal;
-      } U;
-      U.FVal = Val;
-      O << ".word\t0x" << std::hex << (U.UVal >> 32) << std::dec << "\t! double " << Val << "\n";
-      O << ".word\t0x" << std::hex << (U.UVal & 0xffffffffUL) << std::dec << "\t! double " << Val << "\n";
+      O << ".word\t0x" << std::hex << (DoubleToBits(Val) >> 32) << std::dec << "\t! double " << Val << "\n";
+      O << ".word\t0x" << std::hex << (DoubleToBits(Val) & 0xffffffffUL) << std::dec << "\t! double " << Val << "\n";
       return;
     }
     }
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index e06bf50..eb04965 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -29,6 +29,7 @@
 #include "llvm/Support/CFG.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/MathExtras.h"
 #include <algorithm>
 using namespace llvm;
 
@@ -431,18 +432,9 @@
 
     // Otherwise we could not reparse it to exactly the same value, so we must
     // output the string in hexadecimal format!
-    //
-    // Behave nicely in the face of C TBAA rules... see:
-    // http://www.nullstone.com/htmls/category/aliastyp.htm
-    //
-    union {
-      double D;
-      uint64_t U;
-    } V;
-    V.D = CFP->getValue();
     assert(sizeof(double) == sizeof(uint64_t) &&
            "assuming that double is 64 bits!");
-    Out << "0x" << utohexstr(V.U);
+    Out << "0x" << utohexstr(DoubleToBits(CFP->getValue()));
 
   } else if (isa<ConstantAggregateZero>(CV)) {
     Out << "zeroinitializer";
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 2bedef5..a14b690 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -19,6 +19,7 @@
 #include "llvm/SymbolTable.h"
 #include "llvm/Module.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/MathExtras.h"
 #include <algorithm>
 #include <iostream>
 using namespace llvm;
@@ -796,24 +797,14 @@
   struct ConstantCreator<ConstantFP, Type, uint64_t> {
     static ConstantFP *create(const Type *Ty, uint64_t V) {
       assert(Ty == Type::DoubleTy);
-      union {
-        double F;
-        uint64_t I;
-      } T;
-      T.I = V;
-      return new ConstantFP(Ty, T.F);
+      return new ConstantFP(Ty, BitsToDouble(V));
     }
   };
   template<>
   struct ConstantCreator<ConstantFP, Type, uint32_t> {
     static ConstantFP *create(const Type *Ty, uint32_t V) {
       assert(Ty == Type::FloatTy);
-      union {
-        float F;
-        uint32_t I;
-      } T;
-      T.I = V;
-      return new ConstantFP(Ty, T.F);
+      return new ConstantFP(Ty, BitsToFloat(V));
     }
   };
 }
@@ -824,20 +815,10 @@
 ConstantFP *ConstantFP::get(const Type *Ty, double V) {
   if (Ty == Type::FloatTy) {
     // Force the value through memory to normalize it.
-    union {
-      float F;
-      uint32_t I;
-    } T;
-    T.F = (float)V;
-    return FloatConstants.getOrCreate(Ty, T.I);
+    return FloatConstants.getOrCreate(Ty, FloatToBits(V));
   } else {
     assert(Ty == Type::DoubleTy);
-    union {
-      double F;
-      uint64_t I;
-    } T;
-    T.F = V;
-    return DoubleConstants.getOrCreate(Ty, T.I);
+    return DoubleConstants.getOrCreate(Ty, DoubleToBits(V));
   }
 }