[llvm] r341728 - ADT: add <bit> header, implement C++20 bit_cast, use
Richard Smith via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 7 16:28:10 PDT 2018
On Fri, 7 Sep 2018 at 16:08, JF Bastien via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: jfb
> Date: Fri Sep 7 16:08:26 2018
> New Revision: 341728
>
> URL: http://llvm.org/viewvc/llvm-project?rev=341728&view=rev
> Log:
> 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.
>
> Reviewers: javed.absar
>
> Subscribers: dexonsmith, llvm-commits
>
> Differential Revision: https://reviews.llvm.org/D51693
>
> Added:
> llvm/trunk/include/llvm/ADT/bit.h
> Modified:
> llvm/trunk/lib/Support/APInt.cpp
> llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h
> llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h
>
> Added: llvm/trunk/include/llvm/ADT/bit.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/bit.h?rev=341728&view=auto
>
> ==============================================================================
> --- llvm/trunk/include/llvm/ADT/bit.h (added)
> +++ llvm/trunk/include/llvm/ADT/bit.h Fri Sep 7 16:08:26 2018
> @@ -0,0 +1,37 @@
> +//===-- llvm/ADT/bit.h - C++20 <bit> ----------------------------*- C++
> -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// This file implements the C++20 <bit> header.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_ADT_BIT_H
> +#define LLVM_ADT_BIT_H
> +
> +#include <cstring>
> +#include <type_traits>
> +
> +namespace llvm {
> +
> +template <
> + typename To, typename From,
> + typename = typename std::enable_if<sizeof(To) == sizeof(From)>::type,
> + typename =
> + typename
> std::enable_if<std::is_trivially_copyable<To>::value>::type,
> + typename =
> + typename
> std::enable_if<std::is_trivially_copyable<From>::value>::type>
> +inline To bit_cast(const From &from) noexcept {
> + typename std::aligned_storage<sizeof(To), alignof(To)>::type storage;
>
std::aligned_storage should never be used for anything, ever. Use
alignas(To) unsigned char storage[sizeof(To)];
+ std::memcpy(&storage, &from, sizeof(To));
> + return reinterpret_cast<To &>(storage);
> +}
> +
> +} // namespace llvm
> +
> +#endif
>
> Modified: llvm/trunk/lib/Support/APInt.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APInt.cpp?rev=341728&r1=341727&r2=341728&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Support/APInt.cpp (original)
> +++ llvm/trunk/lib/Support/APInt.cpp Fri Sep 7 16:08:26 2018
> @@ -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::GreatestCommonDivi
> }
>
> 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 isSigne
>
> // 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.
>
> Modified:
> llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h?rev=341728&r1=341727&r2=341728&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h
> (original)
> +++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h
> Fri Sep 7 16:08:26 2018
> @@ -16,6 +16,7 @@
>
> #include "llvm/ADT/APFloat.h"
> #include "llvm/ADT/APInt.h"
> +#include "llvm/ADT/bit.h"
> #include "llvm/Support/ErrorHandling.h"
> #include "llvm/Support/MathExtras.h"
> #include <cassert>
> @@ -342,27 +343,23 @@ static inline bool isValidDecodeLogicalI
> //
> static inline float getFPImmFloat(unsigned Imm) {
> // We expect an 8-bit binary encoding of a floating-point number here.
> - union {
> - uint32_t I;
> - float F;
> - } FPUnion;
>
> uint8_t Sign = (Imm >> 7) & 0x1;
> uint8_t Exp = (Imm >> 4) & 0x7;
> uint8_t Mantissa = Imm & 0xf;
>
> - // 8-bit FP iEEEE Float Encoding
> + // 8-bit FP IEEE Float Encoding
> // abcd efgh aBbbbbbc defgh000 00000000 00000000
> //
> // where B = NOT(b);
>
> - FPUnion.I = 0;
> - FPUnion.I |= Sign << 31;
> - FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30;
> - FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25;
> - FPUnion.I |= (Exp & 0x3) << 23;
> - FPUnion.I |= Mantissa << 19;
> - return FPUnion.F;
> + uint32_t I = 0;
> + I |= Sign << 31;
> + I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30;
> + I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25;
> + I |= (Exp & 0x3) << 23;
> + I |= Mantissa << 19;
> + return bit_cast<float>(I);
> }
>
> /// getFP16Imm - Return an 8-bit floating-point version of the 16-bit
>
> Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h?rev=341728&r1=341727&r2=341728&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h (original)
> +++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h Fri Sep 7
> 16:08:26 2018
> @@ -627,27 +627,22 @@ namespace ARM_AM {
> //
> inline float getFPImmFloat(unsigned Imm) {
> // We expect an 8-bit binary encoding of a floating-point number here.
> - union {
> - uint32_t I;
> - float F;
> - } FPUnion;
>
> uint8_t Sign = (Imm >> 7) & 0x1;
> uint8_t Exp = (Imm >> 4) & 0x7;
> uint8_t Mantissa = Imm & 0xf;
>
> - // 8-bit FP iEEEE Float Encoding
> + // 8-bit FP IEEE Float Encoding
> // abcd efgh aBbbbbbc defgh000 00000000 00000000
> //
> // where B = NOT(b);
> -
> - FPUnion.I = 0;
> - FPUnion.I |= Sign << 31;
> - FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30;
> - FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25;
> - FPUnion.I |= (Exp & 0x3) << 23;
> - FPUnion.I |= Mantissa << 19;
> - return FPUnion.F;
> + uint32_t I = 0;
> + I |= Sign << 31;
> + I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30;
> + I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25;
> + I |= (Exp & 0x3) << 23;
> + I |= Mantissa << 19;
> + return bit_cast<float>(F);
> }
>
> /// getFP16Imm - Return an 8-bit floating-point version of the 16-bit
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180907/416b92f0/attachment-0001.html>
More information about the llvm-commits
mailing list