diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 3606c430eed..eb634a627c9 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 #include @@ -742,17 +743,7 @@ public: /// 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 91e82ccb8d3..1a9d87d68a1 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 @@ public: /// 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 @@ public: /// 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 f56c59ad18f..6bb06c3ce46 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 #include @@ -162,29 +163,19 @@ inline void BytecodeReader::read_data(void *Ptr, void *End) { 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 95bbd2e5754..b1f2634296f 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 @@ -139,33 +140,25 @@ inline void BytecodeWriter::output_data(const void *Ptr, const void *End) { 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( (FloatUnion.i & 0xFF ))); - Out.push_back( static_cast( (FloatUnion.i >> 8) & 0xFF)); - Out.push_back( static_cast( (FloatUnion.i >> 16) & 0xFF)); - Out.push_back( static_cast( (FloatUnion.i >> 24) & 0xFF)); + uint32_t i = FloatToBits(FloatVal); + Out.push_back( static_cast( (i & 0xFF ))); + Out.push_back( static_cast( (i >> 8) & 0xFF)); + Out.push_back( static_cast( (i >> 16) & 0xFF)); + Out.push_back( static_cast( (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( (DoubleUnion.i & 0xFF ))); - Out.push_back( static_cast( (DoubleUnion.i >> 8) & 0xFF)); - Out.push_back( static_cast( (DoubleUnion.i >> 16) & 0xFF)); - Out.push_back( static_cast( (DoubleUnion.i >> 24) & 0xFF)); - Out.push_back( static_cast( (DoubleUnion.i >> 32) & 0xFF)); - Out.push_back( static_cast( (DoubleUnion.i >> 40) & 0xFF)); - Out.push_back( static_cast( (DoubleUnion.i >> 48) & 0xFF)); - Out.push_back( static_cast( (DoubleUnion.i >> 56) & 0xFF)); + uint64_t i = DoubleToBits(DoubleVal); + Out.push_back( static_cast( (i & 0xFF ))); + Out.push_back( static_cast( (i >> 8) & 0xFF)); + Out.push_back( static_cast( (i >> 16) & 0xFF)); + Out.push_back( static_cast( (i >> 24) & 0xFF)); + Out.push_back( static_cast( (i >> 32) & 0xFF)); + Out.push_back( static_cast( (i >> 40) & 0xFF)); + Out.push_back( static_cast( (i >> 48) & 0xFF)); + Out.push_back( static_cast( (i >> 56) & 0xFF)); } inline BytecodeBlock::BytecodeBlock(unsigned ID, BytecodeWriter& w, diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index 497e9c89fab..d907d67b5a2 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 @@ void AsmPrinter::emitGlobalConstant(const Constant *CV) { // 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 ab070301b08..2c01982df2b 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -975,23 +975,17 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { // Turn 'store float 1.0, Ptr' -> 'store int 0x12345678, Ptr' if (ConstantFPSDNode *CFP =dyn_cast(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 6afa9d08947..81b08039a47 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -224,12 +224,8 @@ void SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) { N->getValueType(0))); break; case ISD::ConstantFP: { - union { - double DV; - uint64_t IV; - }; - DV = cast(N)->getValue(); - ConstantFPs.erase(std::make_pair(IV, N->getValueType(0))); + uint64_t V = DoubleToBits(cast(N)->getValue()); + ConstantFPs.erase(std::make_pair(V, N->getValueType(0))); break; } case ISD::CONDCODE: @@ -385,14 +381,7 @@ SDOperand SelectionDAG::getConstantFP(double Val, MVT::ValueType VT) { // 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 b29187b154f..fc87afd2062 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 @@ void CWriter::printConstant(Constant *CPV) { 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 @@ bool CWriter::doInitialization(Module &M) { /// 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 @@ void CWriter::printFloatingPointConstants(Function &F) { 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 b29187b154f..fc87afd2062 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 @@ void CWriter::printConstant(Constant *CPV) { 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 @@ bool CWriter::doInitialization(Module &M) { /// 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 @@ void CWriter::printFloatingPointConstants(Function &F) { 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 c8852cca990..4e908a1b95d 100644 --- a/lib/Target/Sparc/SparcAsmPrinter.cpp +++ b/lib/Target/Sparc/SparcAsmPrinter.cpp @@ -247,22 +247,12 @@ void V8Printer::emitGlobalConstant(const Constant *CV) { 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 c8852cca990..4e908a1b95d 100644 --- a/lib/Target/SparcV8/SparcV8AsmPrinter.cpp +++ b/lib/Target/SparcV8/SparcV8AsmPrinter.cpp @@ -247,22 +247,12 @@ void V8Printer::emitGlobalConstant(const Constant *CV) { 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 e06bf50a9d1..eb049654608 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 using namespace llvm; @@ -431,18 +432,9 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, // 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(CV)) { Out << "zeroinitializer"; diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 2bedef55858..a14b6903136 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 #include using namespace llvm; @@ -796,24 +797,14 @@ namespace llvm { struct ConstantCreator { 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 { 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 @@ static ValueMap FloatConstants; 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)); } }