]> granicus.if.org Git - llvm/commitdiff
[ConstExprPreter] Overflow-detecting methods use GCC or clang builtins
authorJF Bastien <jfbastien@apple.com>
Wed, 31 Jul 2019 23:09:18 +0000 (23:09 +0000)
committerJF Bastien <jfbastien@apple.com>
Wed, 31 Jul 2019 23:09:18 +0000 (23:09 +0000)
 Differential Revision: https://reviews.llvm.org/D65536

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367490 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/MathExtras.h

index 40256d102cd9cad24fa2d5007a2a5e1f74516704..a2009c7b8b6a421f115c399abe729140996abae4 100644 (file)
@@ -860,6 +860,9 @@ extern const float huge_valf;
 template <typename T>
 typename std::enable_if<std::is_signed<T>::value, T>::type
 AddOverflow(T X, T Y, T &Result) {
+#if __has_builtin(__builtin_add_overflow)
+  return __builtin_add_overflow(X, Y, &Result);
+#else
   // Perform the unsigned addition.
   using U = typename std::make_unsigned<T>::type;
   const U UX = static_cast<U>(X);
@@ -876,6 +879,7 @@ AddOverflow(T X, T Y, T &Result) {
   if (X < 0 && Y < 0)
     return Result >= 0;
   return false;
+#endif
 }
 
 /// Subtract two signed integers, computing the two's complement truncated
@@ -883,6 +887,9 @@ AddOverflow(T X, T Y, T &Result) {
 template <typename T>
 typename std::enable_if<std::is_signed<T>::value, T>::type
 SubOverflow(T X, T Y, T &Result) {
+#if __has_builtin(__builtin_sub_overflow)
+  return __builtin_sub_overflow(X, Y, &Result);
+#else
   // Perform the unsigned addition.
   using U = typename std::make_unsigned<T>::type;
   const U UX = static_cast<U>(X);
@@ -899,6 +906,7 @@ SubOverflow(T X, T Y, T &Result) {
   if (X >= 0 && Y < 0)
     return Result <= 0;
   return false;
+#endif
 }
 
 
@@ -907,6 +915,9 @@ SubOverflow(T X, T Y, T &Result) {
 template <typename T>
 typename std::enable_if<std::is_signed<T>::value, T>::type
 MulOverflow(T X, T Y, T &Result) {
+#if __has_builtin(__builtin_mul_overflow)
+  return __builtin_mul_overflow(X, Y, &Result);
+#else
   // Perform the unsigned multiplication on absolute values.
   using U = typename std::make_unsigned<T>::type;
   const U UX = X < 0 ? (0 - static_cast<U>(X)) : static_cast<U>(X);
@@ -928,6 +939,7 @@ MulOverflow(T X, T Y, T &Result) {
     return UX > (static_cast<U>(std::numeric_limits<T>::max()) + U(1)) / UY;
   else
     return UX > (static_cast<U>(std::numeric_limits<T>::max())) / UY;
+#endif
 }
 
 } // End llvm namespace