|
template <__signed_or_unsigned_integer _Rp, __signed_or_unsigned_integer _Tp> |
|
_LIBCPP_HIDE_FROM_ABI constexpr _Rp __saturating_cast(_Tp __x) noexcept { |
|
// Saturation is impossible edge case when ((min _Rp) < (min _Tp) && (max _Rp) > (max _Tp)) and it is expected to be |
|
// optimized out by the compiler. |
|
|
|
// Handle overflow |
|
if (std::cmp_less(__x, std::numeric_limits<_Rp>::min())) |
|
return std::numeric_limits<_Rp>::min(); |
|
if (std::cmp_greater(__x, std::numeric_limits<_Rp>::max())) |
|
return std::numeric_limits<_Rp>::max(); |
|
// No overflow |
|
return static_cast<_Rp>(__x); |
|
} |
Currently, we just have this software implementation, but future developments will necessitate an intrinsic:
llvm-project/libcxx/include/__numeric/saturation_arithmetic.h
Lines 105 to 117 in f6f1416
Currently, we just have this software implementation, but future developments will necessitate an intrinsic:
std::simdoverloads for saturating operations wants a SIMD version of the feature, and I'm not sure how easily the current implementation could be turned intovpmovsdwon x86.std::saturating_cast(not yet mailed) extendsstd::saturating_castwith the ability to cast tofloat, which is exactly the existing behavior of llvm.fptoui.sat.*, except that it doesn't require the -fno-strict-float-cast-overflow flag to be specified. Irrespective of whether the proposal makes it in, it would be nice to have a way to emitfptoui.satwithout needing to set a global flag.