xref: /llvm-project-15.0.7/libc/docs/math.rst (revision 628fbbef)
1===========================
2Math Functions in LLVM-libc
3===========================
4
5.. role::  raw-html(raw)
6    :format: html
7
8.. |check| replace:: :raw-html:`&#x2705`
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