1=========================== 2Math Functions in LLVM-libc 3=========================== 4 5.. role:: raw-html(raw) 6 :format: html 7 8.. |check| replace:: :raw-html:`✅` 9 10.. contents:: Table of Contents 11 :depth: 4 12 :local: 13 14Summary 15======= 16 17* This document tracks the status of the implementation of math functions in 18 LLVM libc. 19 20Implementation Requirements / Goals 21=================================== 22 23* The highest priority is to be as accurate as possible, according to the C and 24 IEEE 754 standards. By default, we will aim to be correctly rounded for `all rounding modes <https://en.cppreference.com/w/c/numeric/fenv/FE_round>`_. 25 The current rounding mode of the floating point environment is used to perform 26 computations and produce the final results. 27 28 - To test for correctness, we compare the outputs with other correctly rounded 29 multiple-precision math libraries such as the `GNU MPFR library <https://www.mpfr.org/>`_ 30 or the `CORE-MATH library <https://core-math.gitlabpages.inria.fr/>`_. 31 32* Our next requirement is that the outputs are consistent across all platforms. 33 Notice that the consistency requirement will be satisfied automatically if the 34 implementation is correctly rounded. 35 36* Our last requirement for the implementations is to have good and predicable 37 performance: 38 39 - The average performance should be comparable to other ``libc`` 40 implementations. 41 - The worst case performance should be within 10X-20X of the average. 42 - Platform-specific implementations or instructions could be added whenever it 43 makes sense and provides significant performance boost. 44 45* For other use cases that have strict requirements on the code size, memory 46 footprint, or latency, such as embedded systems, we will aim to be as accurate 47 as possible within the memory or latency budgets, and consistent across all 48 platforms. 49 50 51Source Locations 52================ 53 54- The main source is located at: `libc/src/math <https://github.com/llvm/llvm-project/tree/main/libc/src/math>`_. 55- The tests are located at: `libc/test/src/math <https://github.com/llvm/llvm-project/tree/main/libc/test/src/math>`_. 56- The floating point utilities are located at: `libc/src/__support/FPUtil <https://github.com/llvm/llvm-project/tree/main/libc/src/__support/FPUtil>`_. 57 58Add a new math function to LLVM libc 59==================================== 60 61* To add a new math function, follow the steps at: `libc/src/math/docs/add_math_function.md <https://github.com/llvm/llvm-project/tree/main/libc/src/math/docs/add_math_function.md>`_. 62 63Implementation Status 64===================== 65 66Basic Operations 67---------------- 68 69============== ================ =============== ====================== 70<Func> <Func_f> (float) <Func> (double) <Func_l> (long double) 71============== ================ =============== ====================== 72ceil |check| |check| |check| 73copysign |check| |check| |check| 74fabs |check| |check| |check| 75fdim |check| |check| |check| 76floor |check| |check| |check| 77fmax |check| |check| |check| 78fmin |check| |check| |check| 79fmod |check| |check| 80fpclassify 81frexp |check| |check| |check| 82ilogb |check| |check| |check| 83isfinite 84isgreater 85isgreaterequal 86isinf 87isless 88islessequal 89islessgreater 90isnan 91isnormal 92isubordered 93ldexp |check| |check| |check| 94llrint |check| |check| |check| 95llround |check| |check| |check| 96logb |check| |check| |check| 97lrint |check| |check| |check| 98lround |check| |check| |check| 99modf |check| |check| |check| 100nan 101nearbyint |check| |check| |check| 102nextafter |check| |check| |check| 103nexttoward 104remainder |check| |check| |check| 105remquo |check| |check| |check| 106rint |check| |check| |check| 107round |check| |check| |check| 108scalbn 109signbit 110trunc |check| |check| |check| 111============== ================ =============== ====================== 112 113Higher Math Functions 114--------------------- 115 116============== ================ =============== ====================== 117<Func> <Func_f> (float) <Func> (double) <Func_l> (long double) 118============== ================ =============== ====================== 119acos 120acosh 121asin 122asinh 123atan 124atan2 125atanh 126cbrt 127cos |check| |check| 128cosh 129erf 130erfc 131exp |check| 132exp2 |check| 133expm1 |check| 134fma |check| |check| 135hypot |check| |check| 136lgamma 137log |check| 138log10 |check| 139log1p |check| 140log2 |check| 141pow 142sin |check| |check| 143sincos |check| |check| 144sinh 145sqrt |check| |check| |check| 146tan 147tanh 148tgamma 149============== ================ =============== ====================== 150 151Accuracy of Higher Math Functions 152================================= 153 154============== ================ =============== ====================== 155<Func> <Func_f> (float) <Func> (double) <Func_l> (long double) 156============== ================ =============== ====================== 157cos 0.776 ULPs large 158exp |check| 159exp2 |check| 160expm1 |check| 161fma |check| |check| 162hypot |check| |check| 163log |check| 164log10 |check| 165log1p |check| 166log2 |check| 167sin |check| large 168sincos 0.776 ULPs large 169sqrt |check| |check| |check| 170============== ================ =============== ====================== 171 172Legends: 173 174* |check|: correctly rounded for all 4 rounding modes. 175* CR: correctly rounded for the default rounding mode (round-to-the-nearest, 176 tie-to-even). 177* x ULPs: largest errors recorded. 178 179.. 180 TODO(lntue): Add a new page to discuss about the algorithms used in the 181 implementations and include the link here. 182 183 184Performance 185=========== 186 187* Simple performance testings are located at: `libc/test/src/math/differential_testing <https://github.com/llvm/llvm-project/tree/main/libc/test/src/math/differential_testing>`_. 188 189* We also use the *perf* tool from the `CORE-MATH <https://core-math.gitlabpages.inria.fr/>`_ 190 project: `link <https://gitlab.inria.fr/core-math/core-math/-/tree/master>`_. 191 The performance results from the CORE-MATH's perf tool are reported in the 192 table below, using the system library as reference (such as the `GNU C library <https://www.gnu.org/software/libc/>`_ 193 on Linux). Fmod performance results obtained with "differential_testing". 194 195+--------------+-------------------------------+-------------------------------+-------------------------------------+---------------------------------------------------------------------+ 196| <Func> | Reciprocal throughput (ns) | Latency (ns) | Testing ranges | Testing configuration | 197| +-----------+-------------------+-----------+-------------------+ +------------+-------------------------+--------------+---------------+ 198| | LLVM libc | Reference (glibc) | LLVM libc | Reference (glibc) | | CPU | OS | Compiler | Special flags | 199+==============+===========+===================+===========+===================+=====================================+============+=========================+==============+===============+ 200| cosf | 37 | 32 | 73 | 72 | :math:`[0, 2\pi]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | | 201+--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ 202| expf | 9 | 7 | 44 | 38 | :math:`[-10, 10]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | FMA | 203+--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ 204| exp2f | 25 | 8 | 81 | 37 | :math:`[-10, 10]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | FMA | 205+--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ 206| expm1f | 9 | 44 | 42 | 121 | :math:`[-10, 10]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | FMA | 207+--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ 208| fmodf | 73 | 263 | - | - | [MIN_NORMAL, MAX_NORMAL] | i5 mobile | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | | 209| +-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ 210| | 9 | 11 | - | - | [0, MAX_SUBNORMAL] | i5 mobile | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | | 211+--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ 212| fmod | 595 | 3297 | - | - | [MIN_NORMAL, MAX_NORMAL] | i5 mobile | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | | 213| +-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ 214| | 14 | 13 | - | - | [0, MAX_SUBNORMAL] | i5 mobile | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | | 215+--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ 216| hypotf | 25 | 15 | 64 | 49 | :math:`[-10, 10] \times [-10, 10]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | | 217+--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ 218| logf | 12 | 10 | 56 | 46 | :math:`[e^{-1}, e]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | FMA | 219+--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ 220| log10f | 13 | 25 | 57 | 72 | :math:`[e^{-1}, e]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | FMA | 221+--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ 222| log1pf | 16 | 33 | 61 | 97 | :math:`[e^{-0.5} - 1, e^{0.5} - 1]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | FMA | 223+--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ 224| log2f | 13 | 10 | 57 | 46 | :math:`[e^{-1}, e]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | FMA | 225+--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ 226| sinf | 14 | 26 | 65 | 59 | :math:`[-\pi, \pi]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | FMA | 227+--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ 228 229References 230========== 231 232* `CRLIBM <https://hal-ens-lyon.archives-ouvertes.fr/ensl-01529804/file/crlibm.pdf>`_. 233* `RLIBM <https://people.cs.rutgers.edu/~sn349/rlibm/>`_. 234* `Sollya <https://www.sollya.org/>`_. 235* `The CORE-MATH Project <https://core-math.gitlabpages.inria.fr/>`_. 236* `The GNU C Library (glibc) <https://www.gnu.org/software/libc/>`_. 237* `The GNU MPFR Library <https://www.mpfr.org/>`_. 238