[PR] [RFC] avutil/libm: remove fallbacks for standard C99 math functions (PR #24240)
Kacper Michajłow via ffmpeg-devel <[email protected]>
| Newsgroups | gmane.comp.video.ffmpeg.devel |
|---|---|
| Message-ID | <[email protected]> |
PR #24240 opened by Kacper Michajłow (kasper93) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24240 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24240.patch All of these are mandatory for hosted implementations since C99 and in reality present on every toolchain that passes the C11 requirement. From 67eb8cfff47ae74b227056eca651a79237e0d6b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= <[email protected]> Date: Sat, 22 Aug 2026 16:23:51 +0200 Subject: [PATCH] avutil/libm: remove fallbacks for standard C99 math functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All of these are mandatory for hosted implementations since C99 and in reality present on every toolchain that passes the C11 requirement. Signed-off-by: Kacper Michajłow <[email protected]> --- configure | 59 ----- libavutil/libm.h | 440 +------------------------------------ libavutil/mips/libm_mips.h | 1 - 3 files changed, 1 insertion(+), 499 deletions(-) diff --git a/configure b/configure index 594697b64b..b094d6add1 100755 --- a/configure +++ b/configure @@ -1465,20 +1465,6 @@ int main(void){ $func(); } EOF } -check_mathfunc(){ - log check_mathfunc "$@" - func=$1 - narg=$2 - shift 2 - test $narg = 2 && args="f, g" || args="f" - disable $func - test_ld "cc" "$@" <<EOF && enable $func -#include <math.h> -float foo(float f, float g) { return $func($args); } -int main(void){ return (int) foo; } -EOF -} - check_func_headers(){ log check_func_headers "$@" headers=$1 @@ -2473,38 +2459,6 @@ INTRINSICS_LIST=" intrinsics_sse2 " -MATH_FUNCS=" - atanf - atan2f - cbrt - cbrtf - copysign - cosf - erf - exp2 - exp2f - expf - hypot - isfinite - isinf - isnan - ldexpf - llrint - llrintf - log2 - log2f - log10f - lrint - lrintf - powf - rint - round - roundf - sinf - trunc - truncf -" - SYSTEM_FEATURES=" dos_paths libc_msvcrt @@ -2679,7 +2633,6 @@ HAVE_LIST=" $HAVE_LIST_PUB $HEADERS_LIST $INTRINSICS_LIST - $MATH_FUNCS $SYSTEM_FEATURES $SYSTEM_FUNCS $SYSTEM_LIBRARIES @@ -7264,16 +7217,6 @@ check_lib libdl dlfcn.h "dlopen dlsym" || check_lib libdl dlfcn.h "dlopen dlsym" check_lib libm math.h sin -lm check_host_lib math.h sin -lm -atan2f_args=2 -copysign_args=2 -hypot_args=2 -ldexpf_args=2 -powf_args=2 - -for func in $MATH_FUNCS; do - eval check_mathfunc $func \${${func}_args:-1} $libm_extralibs -done - # these are off by default, so fail if requested and not available enabled avisynth && { require_headers "avisynth/avisynth_c.h avisynth/avs/version.h" && { test_cpp_condition avisynth/avs/version.h "AVS_MAJOR_VER >= 3 && AVS_MINOR_VER >= 7 && AVS_BUGFIX_VER >= 3 || AVS_MAJOR_VER >= 3 && AVS_MINOR_VER > 7 || AVS_MAJOR_VER > 3" || @@ -8177,8 +8120,6 @@ elif enabled_any msvc icl; then disable ebx_available fi fi - # msvcrt10 x64 incorrectly enables log2, only msvcrt12 (MSVC 2013) onwards actually has log2. - check_cpp_condition log2 crtversion.h "_VC_CRT_MAJOR_VERSION >= 12" # the new SSA optimizer in VS2015 U3 is mis-optimizing some parts of the code # Issue has been fixed in MSVC v19.00.24218. test_cpp_condition windows.h "_MSC_FULL_VER >= 190024218" || diff --git a/libavutil/libm.h b/libavutil/libm.h index e560885d5d..224cfa3c6e 100644 --- a/libavutil/libm.h +++ b/libavutil/libm.h @@ -1,5 +1,4 @@ /* - * erf function: Copyright (c) 2006 John Maddock * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -19,7 +18,7 @@ /** * @file - * Replacements for frequently missing libm functions + * Wrapper around math.h with platform-specific optimizations */ #ifndef AVUTIL_LIBM_H @@ -27,447 +26,10 @@ #include <math.h> #include "config.h" -#include "attributes.h" -#if !(HAVE_COPYSIGN && HAVE_HYPOT && HAVE_ISFINITE && HAVE_ISINF && HAVE_ISNAN) -#include "intfloat.h" -#endif #include "mathematics.h" #if HAVE_MIPSFPU && HAVE_INLINE_ASM #include "libavutil/mips/libm_mips.h" #endif /* HAVE_MIPSFPU && HAVE_INLINE_ASM*/ -#if !HAVE_ATANF -#undef atanf -#define atanf(x) ((float)atan(x)) -#endif /* HAVE_ATANF */ - -#if !HAVE_ATAN2F -#undef atan2f -#define atan2f(y, x) ((float)atan2(y, x)) -#endif /* HAVE_ATAN2F */ - -#if !HAVE_POWF -#undef powf -#define powf(x, y) ((float)pow(x, y)) -#endif /* HAVE_POWF */ - -#if !HAVE_CBRT -static av_always_inline double cbrt(double x) -{ - return x < 0 ? -pow(-x, 1.0 / 3.0) : pow(x, 1.0 / 3.0); -} -#endif /* HAVE_CBRT */ - -#if !HAVE_CBRTF -static av_always_inline float cbrtf(float x) -{ - return x < 0 ? -powf(-x, 1.0 / 3.0) : powf(x, 1.0 / 3.0); -} -#endif /* HAVE_CBRTF */ - -#if !HAVE_COPYSIGN -static av_always_inline double copysign(double x, double y) -{ - uint64_t vx = av_double2int(x); - uint64_t vy = av_double2int(y); - return av_int2double((vx & UINT64_C(0x7fffffffffffffff)) | (vy & UINT64_C(0x8000000000000000))); -} -#endif /* HAVE_COPYSIGN */ - -#if !HAVE_COSF -#undef cosf -#define cosf(x) ((float)cos(x)) -#endif /* HAVE_COSF */ - -#if !HAVE_ERF -static inline double ff_eval_poly(const double *coeff, int size, double x) { - double sum = coeff[size-1]; - int i; - for (i = size-2; i >= 0; --i) { - sum *= x; - sum += coeff[i]; - } - return sum; -} - -/** - * erf function - * Algorithm taken from the Boost project, source: - * http://www.boost.org/doc/libs/1_46_1/boost/math/special_functions/erf.hpp - * Use, modification and distribution are subject to the - * Boost Software License, Version 1.0 (see notice below). - * Boost Software License - Version 1.0 - August 17th, 2003 -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - */ -static inline double erf(double z) -{ -#ifndef FF_ARRAY_ELEMS -#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) -#endif - double result; - - /* handle the symmetry: erf(-x) = -erf(x) */ - if (z < 0) - return -erf(-z); - - /* branch based on range of z, and pick appropriate approximation */ - if (z == 0) - return 0; - else if (z < 1e-10) - return z * 1.125 + z * 0.003379167095512573896158903121545171688; - else if (z < 0.5) { - // Maximum Deviation Found: 1.561e-17 - // Expected Error Term: 1.561e-17 - // Maximum Relative Change in Control Points: 1.155e-04 - // Max Error found at double precision = 2.961182e-17 - - static const double y = 1.044948577880859375; - static const double p[] = { - 0.0834305892146531832907, - -0.338165134459360935041, - -0.0509990735146777432841, - -0.00772758345802133288487, - -0.000322780120964605683831, - }; - static const double q[] = { - 1, - 0.455004033050794024546, - 0.0875222600142252549554, - 0.00858571925074406212772, - 0.000370900071787748000569, - }; - double zz = z * z; - return z * (y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), zz) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), zz)); - } - /* here onwards compute erfc */ - else if (z < 1.5) { - // Maximum Deviation Found: 3.702e-17 - // Expected Error Term: 3.702e-17 - // Maximum Relative Change in Control Points: 2.845e-04 - // Max Error found at double precision = 4.841816e-17 - static const double y = 0.405935764312744140625; - static const double p[] = { - -0.098090592216281240205, - 0.178114665841120341155, - 0.191003695796775433986, - 0.0888900368967884466578, - 0.0195049001251218801359, - 0.00180424538297014223957, - }; - static const double q[] = { - 1, - 1.84759070983002217845, - 1.42628004845511324508, - 0.578052804889902404909, - 0.12385097467900864233, - 0.0113385233577001411017, - 0.337511472483094676155e-5, - }; - result = y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), z - 0.5) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), z - 0.5); - result *= exp(-z * z) / z; - return 1 - result; - } - else if (z < 2.5) { - // Max Error found at double precision = 6.599585e-18 - // Maximum Deviation Found: 3.909e-18 - // Expected Error Term: 3.909e-18 - // Maximum Relative Change in Control Points: 9.886e-05 - static const double y = 0.50672817230224609375; - static const double p[] = { - -0.0243500476207698441272, - 0.0386540375035707201728, - 0.04394818964209516296, - 0.0175679436311802092299, - 0.00323962406290842133584, - 0.000235839115596880717416, - }; - static const double q[] = { - 1, - 1.53991494948552447182, - 0.982403709157920235114, - 0.325732924782444448493, - 0.0563921837420478160373, - 0.00410369723978904575884, - }; - result = y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), z - 1.5) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), z - 1.5); - result *= exp(-z * z) / z; - return 1 - result; - } - else if (z < 4.5) { - // Maximum Deviation Found: 1.512e-17 - // Expected Error Term: 1.512e-17 - // Maximum Relative Change in Control Points: 2.222e-04 - // Max Error found at double precision = 2.062515e-17 - static const double y = 0.5405750274658203125; - static const double p[] = { - 0.00295276716530971662634, - 0.0137384425896355332126, - 0.00840807615555585383007, - 0.00212825620914618649141, - 0.000250269961544794627958, - 0.113212406648847561139e-4, - }; - static const double q[] = { - 1, - 1.04217814166938418171, - 0.442597659481563127003, - 0.0958492726301061423444, - 0.0105982906484876531489, - 0.000479411269521714493907, - }; - result = y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), z - 3.5) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), z - 3.5); - result *= exp(-z * z) / z; - return 1 - result; - } - /* differ from Boost here, the claim of underflow of erfc(x) past 5.8 is - * slightly incorrect, change to 5.92 - * (really somewhere between 5.9125 and 5.925 is when it saturates) */ - else if (z < 5.92) { - // Max Error found at double precision = 2.997958e-17 - // Maximum Deviation Found: 2.860e-17 - // Expected Error Term: 2.859e-17 - // Maximum Relative Change in Control Points: 1.357e-05 - static const double y = 0.5579090118408203125; - static const double p[] = { - 0.00628057170626964891937, - 0.0175389834052493308818, - -0.212652252872804219852, - -0.687717681153649930619, - -2.5518551727311523996, - -3.22729451764143718517, - -2.8175401114513378771, - }; - static const double q[] = { - 1, - 2.79257750980575282228, - 11.0567237927800161565, - 15.930646027911794143, - 22.9367376522880577224, - 13.5064170191802889145, - 5.48409182238641741584, - }; - result = y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), 1 / z) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), 1 / z); - result *= exp(-z * z) / z; - return 1 - result; - } - /* handle the nan case, but don't use isnan for max portability */ - else if (z != z) - return z; - /* finally return saturated result */ - else - return 1; -} -#endif /* HAVE_ERF */ - -#if !HAVE_EXPF -#undef expf -#define expf(x) ((float)exp(x)) -#endif /* HAVE_EXPF */ - -#if !HAVE_EXP2 -#undef exp2 -#define exp2(x) exp((x) * M_LN2) -#endif /* HAVE_EXP2 */ - -#if !HAVE_EXP2F -#undef exp2f -#define exp2f(x) ((float)exp2(x)) -#endif /* HAVE_EXP2F */ - -#if !HAVE_ISINF -#undef isinf -/* Note: these do not follow the BSD/Apple/GNU convention of returning -1 for --Inf, +1 for Inf, 0 otherwise, but merely follow the POSIX/ISO mandated spec of -returning a non-zero value for +/-Inf, 0 otherwise. */ -static av_always_inline av_const int avpriv_isinff(float x) -{ - uint32_t v = av_float2int(x); - if ((v & 0x7f800000) != 0x7f800000) - return 0; - return !(v & 0x007fffff); -} - -static av_always_inline av_const int avpriv_isinf(double x) -{ - uint64_t v = av_double2int(x); - if ((v & 0x7ff0000000000000) != 0x7ff0000000000000) - return 0; - return !(v & 0x000fffffffffffff); -} - -#define isinf(x) \ - (sizeof(x) == sizeof(float) \ - ? avpriv_isinff(x) \ - : avpriv_isinf(x)) -#endif /* HAVE_ISINF */ - -#if !HAVE_ISNAN -static av_always_inline av_const int avpriv_isnanf(float x) -{ - uint32_t v = av_float2int(x); - if ((v & 0x7f800000) != 0x7f800000) - return 0; - return v & 0x007fffff; -} - -static av_always_inline av_const int avpriv_isnan(double x) -{ - uint64_t v = av_double2int(x); - if ((v & 0x7ff0000000000000) != 0x7ff0000000000000) - return 0; - return (v & 0x000fffffffffffff) && 1; -} - -#define isnan(x) \ - (sizeof(x) == sizeof(float) \ - ? avpriv_isnanf(x) \ - : avpriv_isnan(x)) -#endif /* HAVE_ISNAN */ - -#if !HAVE_ISFINITE -static av_always_inline av_const int avpriv_isfinitef(float x) -{ - uint32_t v = av_float2int(x); - return (v & 0x7f800000) != 0x7f800000; -} - -static av_always_inline av_const int avpriv_isfinite(double x) -{ - uint64_t v = av_double2int(x); - return (v & 0x7ff0000000000000) != 0x7ff0000000000000; -} - -#define isfinite(x) \ - (sizeof(x) == sizeof(float) \ - ? avpriv_isfinitef(x) \ - : avpriv_isfinite(x)) -#endif /* HAVE_ISFINITE */ - -#if !HAVE_HYPOT -static inline av_const double hypot(double x, double y) -{ - double temp; - x = fabs(x); - y = fabs(y); - - if (isinf(x) || isinf(y)) - return av_int2double(0x7ff0000000000000); - if (x == 0 || y == 0) - return x + y; - if (x < y) { - temp = x; - x = y; - y = temp; - } - - y = y/x; - return x*sqrt(1 + y*y); -} -#endif /* HAVE_HYPOT */ - -#if !HAVE_LDEXPF -#undef ldexpf -#define ldexpf(x, exp) ((float)ldexp(x, exp)) -#endif /* HAVE_LDEXPF */ - -#if !HAVE_LLRINT -#undef llrint -#define llrint(x) ((long long)rint(x)) -#endif /* HAVE_LLRINT */ - -#if !HAVE_LLRINTF -#undef llrintf -#define llrintf(x) ((long long)rint(x)) -#endif /* HAVE_LLRINT */ - -#if !HAVE_LOG2 -#undef log2 -#define log2(x) (log(x) * 1.44269504088896340736) -#endif /* HAVE_LOG2 */ - -#if !HAVE_LOG2F -#undef log2f -#define log2f(x) ((float)log2(x)) -#endif /* HAVE_LOG2F */ - -#if !HAVE_LOG10F -#undef log10f -#define log10f(x) ((float)log10(x)) -#endif /* HAVE_LOG10F */ - -#if !HAVE_SINF -#undef sinf -#define sinf(x) ((float)sin(x)) -#endif /* HAVE_SINF */ - -#if !HAVE_RINT -static inline double rint(double x) -{ - return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5); -} -#endif /* HAVE_RINT */ - -#if !HAVE_LRINT -static av_always_inline av_const long int lrint(double x) -{ - return rint(x); -} -#endif /* HAVE_LRINT */ - -#if !HAVE_LRINTF -static av_always_inline av_const long int lrintf(float x) -{ - return (int)(rint(x)); -} -#endif /* HAVE_LRINTF */ - -#if !HAVE_ROUND -static av_always_inline av_const double round(double x) -{ - return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5); -} -#endif /* HAVE_ROUND */ - -#if !HAVE_ROUNDF -static av_always_inline av_const float roundf(float x) -{ - return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5); -} -#endif /* HAVE_ROUNDF */ - -#if !HAVE_TRUNC -static av_always_inline av_const double trunc(double x) -{ - return (x > 0) ? floor(x) : ceil(x); -} -#endif /* HAVE_TRUNC */ - -#if !HAVE_TRUNCF -static av_always_inline av_const float truncf(float x) -{ - return (x > 0) ? floor(x) : ceil(x); -} -#endif /* HAVE_TRUNCF */ - #endif /* AVUTIL_LIBM_H */ diff --git a/libavutil/mips/libm_mips.h b/libavutil/mips/libm_mips.h index fbf7cf41cc..e40a0cd74d 100644 --- a/libavutil/mips/libm_mips.h +++ b/libavutil/mips/libm_mips.h @@ -71,5 +71,4 @@ static av_always_inline av_const long int lrintf_mips(float x) #undef lrintf #define lrintf(x) lrintf_mips(x) -#define HAVE_LRINTF 1 #endif /* AVUTIL_MIPS_LIBM_MIPS_H */ -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]