[NFC][Py Reformat] Added more commits to .git-blame-ignore-revs
[llvm-project.git] / libc / src / math / docs / add_math_function.md
blob09ac06e15103a53f6496cfb1fdfc41d55c2ee65b
1 # How to add a new math function to LLVM-libc
3 This document is to serve as a cookbook for adding a new math function
4 implementation to LLVM libc.  To add a new function, apart from the actual
5 implementation, one has to follow a few other steps to setup proper registration
6 and shipping of the new function.  Each of these steps will be described in
7 detail below.
9 ## Registration
11 To register the function's entry points for supported OSes and architectures,
12 together with its specifications:
14 - Add entry points `libc.src.math.func` to the following files:
15 ```
16   libc/config/linux/<arch>/entrypoints.txt
17   libc/config/windows/entrypoints.txt
18 ```
19 - Add function specs to the file:
20 ```
21   libc/spec/stdc.td
22 ```
24 ## Implementation
26 The function's actual implementation and its corresponding header should be
27 added to the following locations:
29 - Add `add_math_entrypoint_object(<func>)` to:
30 ```
31   libc/src/math/CMakeLists.txt
32 ```
33 - Add function declaration (under `__llvm_libc` namespace) to:
34 ```
35   libc/src/math/<func>.h
36 ```
37 - Add function definition to:
38 ```
39   libc/src/math/generic/<func>.cpp
40 ```
41 - Add the corresponding `add_entrypoint_object` to:
42 ```
43   libc/src/math/generic/CMakeLists.txt
44 ```
45 - Add architectural specific implementations to:
46 ```
47   libc/src/math/<arch>/<func>.cpp
48 ```
50 ### Floating point utility
52 - Floating point utilities and math functions that are also used internally are
53 located at:
54 ```
55   libc/src/__support/FPUtils
56 ```
57 - These are preferred to be included as header-only.
58 - To manipulate bits of floating point numbers, use the template class
59 `__llvm_libc::fputil::FPBits<>` in the header file:
60 ```
61   libc/src/__support/FPUtils/FPBits.h
62 ```
64 ## Testing
66 ### MPFR utility
68 In addition to the normal testing macros such as `EXPECT_EQ, ASSERT_THAT, ...`
69 there are two special macros `ASSERT_MPFR_MATCH` and `EXPECT_MPFR_MATCH` to
70 compare your outputs with the corresponding MPFR function.  In
71 order for your new function to be supported by these two macros,
72 the following files will need to be updated:
74 - Add the function enum to `__llvm_libc::testing::mpfr::Operation` in the
75 header file:
76 ```
77   libc/utils/MPFRWrapper/MPFRUtils.h
78 ```
79 - Add support for `func` in the `MPFRNumber` class and the corresponding link
80 between the enum and its call to the file:
81 ```
82   libc/utils/MPFRWrapper/MPFRUtils.cpp
83 ```
85 ### Unit tests
87 Besides the usual testing macros like `EXPECT_EQ, ASSERT_TRUE, ...` there are
88 testing macros specifically used for floating point values, such as
89 `EXPECT_FP_EQ, ASSERT_FP_LE, ...`
91 - Add unit test to:
92 ```
93   libc/test/src/math/<func>_test.cpp
94 ```
95 - Add the corresponding entry point to:
96 ```
97   libc/test/src/math/CMakeLists.txt
98 ```
100 ### Exhaustive tests
102 Exhaustive tests are long-running tests that are not included when you run
103 `ninja check-libc`.  These exhaustive tests are added and manually run in
104 order to find exceptional cases for your function's implementation.
106 - Add an exhaustive test to:
108   libc/test/src/math/exhaustive/<func>_test.cpp
110 - Add the corresponding entry point to:
112   libc/test/src/math/exhaustive/CMakeLists.txt
114 - The template class `LlvmLibcExhaustiveTest` located at:
116   libc/test/src/math/exhaustive/exhaustive_test.h
118 can be inherited for conveniently parallelizing the exhaustive tests.
120 ### Performance tests
122 Performance tests compare your function's implementation with the system libc
123 implementation (which is very often glibc).
125 - Add a performance test to:
127   libc/test/src/math/differential_testing/<func>_perf.cpp
129 - Add the corresponding entry point to:
131   libc/test/src/math/differential_testing/CMakeLists.txt
134 ## Build and Run
136 - Check out the LLVM source tree:
138   $ git clone https://github.com/llvm/llvm-project.git
141 - Setup projects with CMake:
143   $ cd llvm-project
144   $ mkdir build
145   $ cd build
146   $ cmake ../llvm -G Ninja \
147   -DLLVM_ENABLE_PROJECTS="llvm;libc" \
148   -DCMAKE_BUILD_TYPE=Debug \
149   -DCMAKE_C_COMPILER=clang \
150   -DCMAKE_CXX_COMPILER=clang++
153 - Build the whole `libc`:
155   $ ninja libc
158 - Run all unit tests:
160   $ ninja check-libc
163 - Build and Run a specific unit test:
165   $ ninja libc.test.src.math.<func>_test
166   $ projects/libc/test/src/math/libc.test.src.math.<func>_test
169 - Build and Run exhaustive test (might take hours to run):
171   $ ninja libc.test.src.math.exhaustive.<func>_test
172   $ projects/libc/test/src/math/exhaustive/libc.test.src.math.exhaustive.<func>_test
175 - Build and Run performance test:
177   $ ninja libc.test.src.math.differential_testing.<func>_perf
178   $ projects/libc/test/src/math/differential_testing/libc.test.src.math.differential_testing.<func>_perf
179   $ cat <func>_perf.log
182 ## Code reviews
184 We follow the code review process of LLVM with Phabricator:
186   https://llvm.org/docs/Phabricator.html