diff options
author | Dale Curtis <dalecurtis@chromium.org> | 2020-05-01 10:20:43 -0700 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2020-05-27 21:05:52 +0200 |
commit | fda1c74539d7b0680f34ca765c2c0055d8f2bb3e (patch) | |
tree | c51f11b609be7b4bc60381d763e5cca7a8bb3ea6 | |
parent | 61c1df73d661d043364b1c3112c39ea343c577cb (diff) | |
download | ffmpeg-fda1c74539d7b0680f34ca765c2c0055d8f2bb3e.tar.gz |
Use gcc/clang builtins for av_sat_(add|sub)_64_c if available.
Signed-off-by: Dale Curtis <dalecurtis@chromium.org>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r-- | libavutil/attributes.h | 6 | ||||
-rw-r--r-- | libavutil/common.h | 10 |
2 files changed, 16 insertions, 0 deletions
diff --git a/libavutil/attributes.h b/libavutil/attributes.h index ced108aa2c..ab2a1fdd0e 100644 --- a/libavutil/attributes.h +++ b/libavutil/attributes.h @@ -34,6 +34,12 @@ # define AV_GCC_VERSION_AT_MOST(x,y) 0 #endif +#ifdef __has_builtin +# define AV_HAS_BUILTIN(x) __has_builtin(x) +#else +# define AV_HAS_BUILTIN(x) false +#endif + #ifndef av_always_inline #if AV_GCC_VERSION_AT_LEAST(3,1) # define av_always_inline __attribute__((always_inline)) inline diff --git a/libavutil/common.h b/libavutil/common.h index 7a774fc448..2777cea9f9 100644 --- a/libavutil/common.h +++ b/libavutil/common.h @@ -299,11 +299,16 @@ static av_always_inline int av_sat_dsub32_c(int a, int b) * @return sum with signed saturation */ static av_always_inline int64_t av_sat_add64_c(int64_t a, int64_t b) { +#if (!defined(__INTEL_COMPILER) && AV_GCC_VERSION_AT_LEAST(5,1)) || AV_HAS_BUILTIN(__builtin_add_overflow) + int64_t tmp; + return !__builtin_add_overflow(a, b, &tmp) ? tmp : (tmp < 0 ? INT64_MAX : INT64_MIN); +#else if (b >= 0 && a >= INT64_MAX - b) return INT64_MAX; if (b <= 0 && a <= INT64_MIN - b) return INT64_MIN; return a + b; +#endif } /** @@ -314,11 +319,16 @@ static av_always_inline int64_t av_sat_add64_c(int64_t a, int64_t b) { * @return difference with signed saturation */ static av_always_inline int64_t av_sat_sub64_c(int64_t a, int64_t b) { +#if (!defined(__INTEL_COMPILER) && AV_GCC_VERSION_AT_LEAST(5,1)) || AV_HAS_BUILTIN(__builtin_sub_overflow) + int64_t tmp; + return !__builtin_sub_overflow(a, b, &tmp) ? tmp : (tmp < 0 ? INT64_MAX : INT64_MIN); +#else if (b <= 0 && a >= INT64_MAX + b) return INT64_MAX; if (b >= 0 && a <= INT64_MIN + b) return INT64_MIN; return a - b; +#endif } /** |