#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/iterator"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
#include <cassert>
#include <vector>
/// 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; }
#include "llvm/Constant.h"
#include "llvm/Type.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
namespace llvm {
/// 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
/// 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:
#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>
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
#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>
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,
#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;
// 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;
}
// 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;
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:
// 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);
#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"
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);
/// 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
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!");
#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"
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);
/// 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
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!");
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;
}
}
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;
}
}
#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;
// 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";
#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;
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));
}
};
}
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));
}
}