diff options
author | JF Bastien <jfbastien@apple.com> | 2018-09-08 03:55:25 +0000 |
---|---|---|
committer | JF Bastien <jfbastien@apple.com> | 2018-09-08 03:55:25 +0000 |
commit | c4986cef12cd3d6f2256a938e50007695ddd9673 (patch) | |
tree | f67238fbb9d21ebb47df51eb9909b566ece819a2 /llvm/lib/Support/APInt.cpp | |
parent | 58963e4396d6557aa8509c90ef753a3f41e5f662 (diff) | |
download | bcm5719-llvm-c4986cef12cd3d6f2256a938e50007695ddd9673.tar.gz bcm5719-llvm-c4986cef12cd3d6f2256a938e50007695ddd9673.zip |
ADT: add <bit> header, implement C++20 bit_cast, use
Summary: I saw a few places that were punning through a union of FP and integer, and that made me sad. Luckily, C++20 adds bit_cast for exactly that purpose. Implement our own version in ADT (without constexpr, leaving us a bit sad), and use it in the few places my grep-fu found silly union punning.
This was originally committed as r341728 and reverted in r341730.
Reviewers: javed.absar, steven_wu, srhines
Subscribers: dexonsmith, llvm-commits
Differential Revision: https://reviews.llvm.org/D51693
llvm-svn: 341741
Diffstat (limited to 'llvm/lib/Support/APInt.cpp')
-rw-r--r-- | llvm/lib/Support/APInt.cpp | 21 |
1 files changed, 7 insertions, 14 deletions
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index f3c2ca5dab9..f2f5cca946f 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/bit.h" #include "llvm/Config/llvm-config.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -712,24 +713,20 @@ APInt llvm::APIntOps::GreatestCommonDivisor(APInt A, APInt B) { } APInt llvm::APIntOps::RoundDoubleToAPInt(double Double, unsigned width) { - union { - double D; - uint64_t I; - } T; - T.D = Double; + uint64_t I = bit_cast<uint64_t>(Double); // Get the sign bit from the highest order bit - bool isNeg = T.I >> 63; + bool isNeg = I >> 63; // Get the 11-bit exponent and adjust for the 1023 bit bias - int64_t exp = ((T.I >> 52) & 0x7ff) - 1023; + int64_t exp = ((I >> 52) & 0x7ff) - 1023; // If the exponent is negative, the value is < 0 so just return 0. if (exp < 0) return APInt(width, 0u); // Extract the mantissa by clearing the top 12 bits (sign + exponent). - uint64_t mantissa = (T.I & (~0ULL >> 12)) | 1ULL << 52; + uint64_t mantissa = (I & (~0ULL >> 12)) | 1ULL << 52; // If the exponent doesn't shift all bits out of the mantissa if (exp < 52) @@ -806,12 +803,8 @@ double APInt::roundToDouble(bool isSigned) const { // The leading bit of mantissa is implicit, so get rid of it. uint64_t sign = isNeg ? (1ULL << (APINT_BITS_PER_WORD - 1)) : 0; - union { - double D; - uint64_t I; - } T; - T.I = sign | (exp << 52) | mantissa; - return T.D; + uint64_t I = sign | (exp << 52) | mantissa; + return bit_cast<double>(I); } // Truncate to new width. |