[libc++] Use saturation builtins directly for {add,sub}_sat (#165228)
This doesn't improve performance (except with optimizations disabled),
since the compiler is able to fold our current implementation. However,
it does significantly reduce the amount of code the compiler has to sift
through, reducing compile times a bit.
GitOrigin-RevId: d4222bf9e2175dc8d0707442802a222d652d0116
diff --git a/include/__numeric/saturation_arithmetic.h b/include/__numeric/saturation_arithmetic.h
index 9bd3af1..7a7410b 100644
--- a/include/__numeric/saturation_arithmetic.h
+++ b/include/__numeric/saturation_arithmetic.h
@@ -30,6 +30,9 @@
template <__signed_or_unsigned_integer _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr _Tp __add_sat(_Tp __x, _Tp __y) noexcept {
+# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 2101
+ return __builtin_elementwise_add_sat(__x, __y);
+# else
if (_Tp __sum; !__builtin_add_overflow(__x, __y, std::addressof(__sum)))
return __sum;
// Handle overflow
@@ -44,10 +47,14 @@
// Overflows if (x < 0 && y < 0)
return std::numeric_limits<_Tp>::min();
}
+# endif
}
template <__signed_or_unsigned_integer _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr _Tp __sub_sat(_Tp __x, _Tp __y) noexcept {
+# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 2101
+ return __builtin_elementwise_sub_sat(__x, __y);
+# else
if (_Tp __sub; !__builtin_sub_overflow(__x, __y, std::addressof(__sub)))
return __sub;
// Handle overflow
@@ -63,6 +70,7 @@
// Overflows if (x < 0 && y > 0)
return std::numeric_limits<_Tp>::min();
}
+# endif
}
template <__signed_or_unsigned_integer _Tp>