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]

Reply via email to