[llvm] [OpenMP] Use __builtin_bit_cast instead of UB type punning (PR #122325)
Joseph Huber via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 9 11:59:24 PST 2025
https://github.com/jhuber6 updated https://github.com/llvm/llvm-project/pull/122325
>From 118a5a7fbe3af9a01600bbce2c06f42d862ae514 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Thu, 9 Jan 2025 11:53:26 -0600
Subject: [PATCH] [OpenMP] Use __builtin_bit_cast instead of UB type punning
Summary:
Fixes type punning, moved out of shared utils because this isn't present
in GCC 7.4 and isn't used outside of the device runtime anyway.
---
offload/DeviceRTL/include/DeviceUtils.h | 5 ++++
offload/DeviceRTL/include/Synchronization.h | 32 ++++++++++-----------
offload/DeviceRTL/src/Mapping.cpp | 8 +++---
offload/include/Shared/Utils.h | 5 ----
4 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/offload/DeviceRTL/include/DeviceUtils.h b/offload/DeviceRTL/include/DeviceUtils.h
index fb00d6c7552557..fa66b973a4f5e7 100644
--- a/offload/DeviceRTL/include/DeviceUtils.h
+++ b/offload/DeviceRTL/include/DeviceUtils.h
@@ -60,6 +60,11 @@ struct remove_addrspace<T [[clang::address_space(N)]]> : type_identity<T> {};
template <class T>
using remove_addrspace_t = typename remove_addrspace<T>::type;
+template <typename To, typename From> inline To bitCast(From V) {
+ static_assert(sizeof(To) == sizeof(From), "Bad conversion");
+ return __builtin_bit_cast(To, V);
+}
+
/// Return the value \p Var from thread Id \p SrcLane in the warp if the thread
/// is identified by \p Mask.
int32_t shuffle(uint64_t Mask, int32_t Var, int32_t SrcLane, int32_t Width);
diff --git a/offload/DeviceRTL/include/Synchronization.h b/offload/DeviceRTL/include/Synchronization.h
index ae065850d824c2..e1968675550d49 100644
--- a/offload/DeviceRTL/include/Synchronization.h
+++ b/offload/DeviceRTL/include/Synchronization.h
@@ -98,20 +98,20 @@ template <typename Ty, typename V = utils::remove_addrspace_t<Ty>>
utils::enable_if_t<utils::is_same_v<V, float>, V>
max(Ty *Address, V Val, atomic::OrderingTy Ordering) {
if (Val >= 0)
- return utils::convertViaPun<float>(
- max((int32_t *)Address, utils::convertViaPun<int32_t>(Val), Ordering));
- return utils::convertViaPun<float>(
- min((uint32_t *)Address, utils::convertViaPun<uint32_t>(Val), Ordering));
+ return utils::bitCast<float>(
+ max((int32_t *)Address, utils::bitCast<int32_t>(Val), Ordering));
+ return utils::bitCast<float>(
+ min((uint32_t *)Address, utils::bitCast<uint32_t>(Val), Ordering));
}
template <typename Ty, typename V = utils::remove_addrspace_t<Ty>>
utils::enable_if_t<utils::is_same_v<V, double>, V>
max(Ty *Address, V Val, atomic::OrderingTy Ordering) {
if (Val >= 0)
- return utils::convertViaPun<double>(
- max((int64_t *)Address, utils::convertViaPun<int64_t>(Val), Ordering));
- return utils::convertViaPun<double>(
- min((uint64_t *)Address, utils::convertViaPun<uint64_t>(Val), Ordering));
+ return utils::bitCast<double>(
+ max((int64_t *)Address, utils::bitCast<int64_t>(Val), Ordering));
+ return utils::bitCast<double>(
+ min((uint64_t *)Address, utils::bitCast<uint64_t>(Val), Ordering));
}
template <typename Ty, typename V = utils::remove_addrspace_t<Ty>>
@@ -126,10 +126,10 @@ template <typename Ty, typename V = utils::remove_addrspace_t<Ty>>
utils::enable_if_t<utils::is_same_v<V, float>, V>
min(Ty *Address, V Val, atomic::OrderingTy Ordering) {
if (Val >= 0)
- return utils::convertViaPun<float>(
- min((int32_t *)Address, utils::convertViaPun<int32_t>(Val), Ordering));
- return utils::convertViaPun<float>(
- max((uint32_t *)Address, utils::convertViaPun<uint32_t>(Val), Ordering));
+ return utils::bitCast<float>(
+ min((int32_t *)Address, utils::bitCast<int32_t>(Val), Ordering));
+ return utils::bitCast<float>(
+ max((uint32_t *)Address, utils::bitCast<uint32_t>(Val), Ordering));
}
// TODO: Implement this with __atomic_fetch_max and remove the duplication.
@@ -138,10 +138,10 @@ utils::enable_if_t<utils::is_same_v<V, double>, V>
min(Ty *Address, utils::remove_addrspace_t<Ty> Val,
atomic::OrderingTy Ordering) {
if (Val >= 0)
- return utils::convertViaPun<double>(
- min((int64_t *)Address, utils::convertViaPun<int64_t>(Val), Ordering));
- return utils::convertViaPun<double>(
- max((uint64_t *)Address, utils::convertViaPun<uint64_t>(Val), Ordering));
+ return utils::bitCast<double>(
+ min((int64_t *)Address, utils::bitCast<int64_t>(Val), Ordering));
+ return utils::bitCast<double>(
+ max((uint64_t *)Address, utils::bitCast<uint64_t>(Val), Ordering));
}
template <typename Ty, typename V = utils::remove_addrspace_t<Ty>>
diff --git a/offload/DeviceRTL/src/Mapping.cpp b/offload/DeviceRTL/src/Mapping.cpp
index 881bd12f034051..8583a539824c82 100644
--- a/offload/DeviceRTL/src/Mapping.cpp
+++ b/offload/DeviceRTL/src/Mapping.cpp
@@ -371,8 +371,8 @@ int ompx_shfl_down_sync_i(uint64_t mask, int var, unsigned delta, int width) {
float ompx_shfl_down_sync_f(uint64_t mask, float var, unsigned delta,
int width) {
- return utils::convertViaPun<float>(utils::shuffleDown(
- mask, utils::convertViaPun<int32_t>(var), delta, width));
+ return utils::bitCast<float>(
+ utils::shuffleDown(mask, utils::bitCast<int32_t>(var), delta, width));
}
long ompx_shfl_down_sync_l(uint64_t mask, long var, unsigned delta, int width) {
@@ -381,8 +381,8 @@ long ompx_shfl_down_sync_l(uint64_t mask, long var, unsigned delta, int width) {
double ompx_shfl_down_sync_d(uint64_t mask, double var, unsigned delta,
int width) {
- return utils::convertViaPun<double>(utils::shuffleDown(
- mask, utils::convertViaPun<int64_t>(var), delta, width));
+ return utils::bitCast<double>(
+ utils::shuffleDown(mask, utils::bitCast<int64_t>(var), delta, width));
}
}
diff --git a/offload/include/Shared/Utils.h b/offload/include/Shared/Utils.h
index 83a82678312c13..523e6bc505b81d 100644
--- a/offload/include/Shared/Utils.h
+++ b/offload/include/Shared/Utils.h
@@ -68,11 +68,6 @@ inline uint32_t popc(uint64_t V) {
return __builtin_popcountl(V);
}
-template <typename DstTy, typename SrcTy> inline DstTy convertViaPun(SrcTy V) {
- static_assert(sizeof(DstTy) == sizeof(SrcTy), "Bad conversion");
- return *((DstTy *)(&V));
-}
-
} // namespace utils
#endif // OMPTARGET_SHARED_UTILS_H
More information about the llvm-commits
mailing list