Lay the ground for C++26 `constexpr` math functions:
- Introduce `LIBC_ENABLE_CONSTEXPR` macro switch to specify the desire
of `constexpr`-only code route.
- Introduce `LIBC_HAS_CONSTANT_EVALUATION` to indicate that we are using
`constexpr`-only code in all dependent functions.
- Introduce `LIBC_CONSTEXPR` macro qualifier to aid in altering the
signature of non-`constexpr` functions.
Note that non-`constexpr` qualified functions are caused by the
exploitation of non-`constexpr` compatible utils, resulting in
non-qualified dependent function, but it can be modified to be qualified
using other code routes.
If the function is `constexpr` compatible, then it's prohibited to use
`LIBC_CONSTEXPR` as a function qualifier. We only qualify it with
`constexpr` as usual.
`LIBC_CONSTEXPR` may or may not evaluate to `constexpr` depending on the
environment configurations, thus it's only used to modify the function
signature in constant evaluation context and remove the qualifier if
it's not desired (depending on provided configurations).
Possible side effects:
- Current qualified routes may or may not produce the desired ULP, this
is implementation dependent (function by function basis) and needs
further testing of the chosen code route.
- The shared tests in the current configuration can still compile with
unsupported compiler. I didn't want to raise compilation error with
unsupported compilers now, but we need to push compiler support with
newer versions for this one to work as intended.
Added entrypoints:
- baremetal/arm
- baremetal/aarch64
- baremetal/riscv
- darwin/aarch64
- linux/aarch64
- linux/arm
- linux/riscv
- linux/x86_64
- windows
Also added the unit test for iswpunct.
Part of the issue: #185136
Add support for %ls in printf by calling internal string converter and
add relevant end-to-end sprintf test. Additionally, modified printf
parser for recognizing length modifier. This also disables wide string
support on windows
and other unsupported platforms.
Co-authored-by: shubhe25p <shubhp@mbm3a24.local>
The standard streams should be defined the same as other public symbols,
even though they're variables rather than functions: we should have
public and private symbol which are aliases, and all internal uses
should use the private symbol to avoid GOT relocations.
This change introduces a new macro `LLVM_LIBC_VARIABLE` which is the
equivalent of `LLVM_LIBC_FUNCTION` and it refactors the existing
definitions of standard streams for BareMetal, Linux and GPU to use this
macro.
The variadic template helper `load_aligned` performs a specific case of
an unaligned integer load, by loading a sequence of integers from memory
at addresses expected to be aligned, and glues the results back together
with shifts and ORs into an output.
The implementation works by performing the first load, recursing on a
shorter parameter type list for the rest, and recombining via
first | (rest << size_of_first) // if little-endian
(first << size_of_first) | rest // if big-endian
But the big-endian case is wrong: it should shift left by the size of
the _rest_ of the types, not the size of the first. In the case where
you load 8, 16 and 8 bits from an odd address, you want
(first_byte << 24) | (middle_halfword << 8) | (last_byte)
but in fact we were calculating
(first_byte << 8) | (middle_halfword << 16) | (last_byte)
leading to three out of every four bytes being permuted in a memcpy from
an odd to an even address.
closes#180171
part of #177259
Here are some extra changes apart from the usual which were needed
1. `libc/src/__support/FPUtil/generic/add_sub.h` → +0 -0 error
2. `libc/src/__support/FPUtil/generic/FMA.h` → implemented to handle
fmabf16(Normal,Normal,+/-INF)
```jsx
/home/runner/work/llvm-project/llvm-project/libc/test/src/math/fmabf16_test.cpp:62: FAILURE
Failed to match __llvm_libc_23_0_0_git::fmabf16(x, y, z) against LIBC_NAMESPACE::testing::mpfr::get_mpfr_matcher<mpfr::Operation::Fma>( input, __llvm_libc_23_0_0_git::fmabf16(x, y, z), 0.5, mpfr::RoundingMode::Nearest).
Input decimal: x: 338953138925153547590470800371487866880.00000000000000000000000000000000000000000000000000 y: 338953138925153547590470800371487866880.00000000000000000000000000000000000000000000000000 z: -inf
First input bits: 0x7F7F = (S: 0, E: 0x00FE, M: 0x007F)
Second input bits: 0x7F7F = (S: 0, E: 0x00FE, M: 0x007F)
Third input bits: (-Infinity)
Libc result: nan
MPFR result: -inf
Libc floating point result bits: (NaN)
MPFR rounded bits: (-Infinity)
```
1. ~~`libc/src/__support/FPUtil/bfloat16.h` → to handle *= operator for
Bfloat16 ( uses the already available mult operator)~~
moved to #182882
The exhaustive test currently includes subnormal range and for checking
for specific edge cases . This is due to the repeated failure at <2^32
input space specifically only for ubuntu 24.04 and 24.04-arm
The removed tests included -> PositiveRange and NegativeRange for
Normals and an extra positive test for subnormals/Denormals
Let me know if there are any changes expected or anything I missed in
this .
cc: @lntue @krishna2803 @overmighty
The hdrgen tests are small and quick to run, so there's little harm in
running them under the main test target `check-libc`. Consequently they
will be run by the CI jobs.
- Added entry points for `iswalnum` for the following platforms:
- baremetal/arm
- baremetal/riscv
- dawin/aarch64
- linux/x86_64
- linux/arm
- linux/aarch64
- linux/riscv
- windows
- Added a unit test for `iswalnum`
part of #185136
This PR intends to add entrypoints and some smoke tests for `iswxdigit`
function
Changes made are :-
- Added entrypoint for `iswxdigit` in wctype.yaml
- Added CMake entrypoint object for `iswxdigit`
- Added Header and implementation in `iswxdigit.h` and `iswxdigit.cpp`
- Added test for `iswxdigit` in iswxdigit_test.cpp
- Added `iswxdigit` in entrypoints.txt for available platforms
Tested using = `ninja libc.test.src.wctype.iswxdigit_test.__unit__`
passes all tests
part of #185136
part of https://github.com/llvm/llvm-project/issues/185136;
This PR adds public entrypoints for the wide character classification
function iswgraph in LLVM libc, using the same pattern as the existing
iswalpha entrypoint.
using bellow cmd to test:
```shell
ninja libc.test.src.wctype.iswgraph_test.__unit__
```
Summary:
This builds off the pattern to add support for more of the standard
operations. The reductions could concievably use the AMDGPU builtins
later once we can enable DPP or other optimizations.
Changes include:
- Added iswlower entrypoint in wctype.yaml to expose the function
- Created iswlower.h header and iswlower.cpp implementation
- Added CMake entrypoint object for iswlower
- Created unit test in iswlower_test.cpp
- Added test entry to wctype CMakeLists.txt
this PR helps in exposing iswlower which internally calls islower on
wide character
built using : ninja -C build libc
tested using : ninja libc_wctype_unittests and all the 3 tests passed
resolves issue #185136
Currently, we have accuracy issues and some points fail in the asinpif
exhaustive test. This change fixes it by increasing the degree of the
used polynomial
```
-- Testing for FE_TONEAREST in range [0x0, 0x7f800000) --
Failed to match Func(x) against LIBC_NAMESPACE::testing::mpfr::get_mpfr_matcher<Op>( x, Func(x), 0.5, rounding).
Match value not within tolerance value of MPFR result:
Input decimal: 0.00000011348398487598387873731553554534912109375000
Input bits: 0x33F3B47B = (S: 0, E: 0x0067, M: 0x0073B47B)
Match decimal: 0.00000003612307253320068411994725465774536132812500
Match bits: 0x331B25BD = (S: 0, E: 0x0066, M: 0x001B25BD)
MPFR result: 0.00000003612307608591436292044818401336669921875000
MPFR rounded: 0x331B25BE = (S: 0, E: 0x0066, M: 0x001B25BE)
ULP error: 1.00000000000000000000000000000000000000000000000000
Test failed for 1 inputs in range: 871366656 to 872415232 [0x33f00000, 0x34000000), [0x1.ep-24, 0x1p-23)
Match value not within tolerance value of MPFR result:
Input decimal: 0.00000356030955117603298276662826538085937500000000
Input bits: 0x366EEDA7 = (S: 0, E: 0x006C, M: 0x006EEDA7)
Match decimal: 0.00000113328167117288103327155113220214843750000000
Match bits: 0x35981B43 = (S: 0, E: 0x006B, M: 0x00181B43)
MPFR result: 0.00000113328178485971875488758087158203125000000000
MPFR rounded: 0x35981B44 = (S: 0, E: 0x006B, M: 0x00181B44)
ULP error: 1.00000000000000000000000000000000000000000000000000
Test failed for 1 inputs in range: 912261120 to 913309696 [0x36600000, 0x36700000), [0x1.cp-19, 0x1.ep-19)
Match value not within tolerance value of MPFR result:
Input decimal: -0.00000011348398487598387873731553554534912109375000
Input bits: 0xB3F3B47B = (S: 1, E: 0x0067, M: 0x0073B47B)
Match decimal: -0.00000003612307253320068411994725465774536132812500
Match bits: 0xB31B25BD = (S: 1, E: 0x0066, M: 0x001B25BD)
MPFR result: -0.00000003612307608591436292044818401336669921875000
MPFR rounded: 0xB31B25BE = (S: 1, E: 0x0066, M: 0x001B25BE)
ULP error: 1.00000000000000000000000000000000000000000000000000
Test failed for 1 inputs in range: 3018850304 to 3019898880 [0xb3f00000, 0xb4000000), [-0x1.ep-24, -0x1p-23)
Match value not within tolerance value of MPFR result:
Input decimal: -0.00000356030955117603298276662826538085937500000000
Input bits: 0xB66EEDA7 = (S: 1, E: 0x006C, M: 0x006EEDA7)
Match decimal: -0.00000113328167117288103327155113220214843750000000
Match bits: 0xB5981B43 = (S: 1, E: 0x006B, M: 0x00181B43)
MPFR result: -0.00000113328178485971875488758087158203125000000000
MPFR rounded: 0xB5981B44 = (S: 1, E: 0x006B, M: 0x00181B44)
ULP error: 1.00000000000000000000000000000000000000000000000000
Test failed for 1 inputs in range: 3059744768 to 3060793344 [0xb6600000, 0xb6700000), [-0x1.cp-19, -0x1.ep-19)
```
According to section 7.24.1 of the C standard, character comparison in
string functions must be performed as if the characters had the type
`unsigned char`.
The previous implementations of `strcmp`, `strncmp`, and `strcoll` were
doing a direct subtraction of `char` values. On platforms where `char`
is signed, this resulted in incorrect negative values being returned
when characters exceeding 127 were being compared.
This patch fixes the comparison functions to explicitly cast the
character values to `unsigned char` prior to computing their difference.
It also adds regression tests to ensure the comparison behaves correctly
for ASCII values greater than 127.
`sockaddr_un` structure is supposed to be provided by the `<sys/un.h>`
header. Add this header to llvm-libc, and move the declaration of
`sockaddr_un` there from `<sys/socket.h>`. See
https://man7.org/linux/man-pages/man0/sys_un.h.0p.html
Add proxy headers for the `<sys/socket.h>` macro (like `AF_UNIX`) and
for the `struct sockaddr_un` so that the tests can be more hermetic and
avoid system header inclusion.
Summary:
This was previously a Trieber stack, which is a perfectly fine generic
and lock-free data structure. However, this used some expensive CAS
operations and had issues with ABA. Because the only user of this was
the slab cache mechanism, we can pretty safely specialize it. Instead,
we simply search a fixed size buffer for some sentinal values and CAS
into it.
For allocations that only ever hit the cache, this improves performance
from ~9000 cycles to ~6000 cycles and similar improvements for workloads
that feel the pain of small thread counts hitting the cache.
The lit-based test runner introduced in c776a52f only discovered
libc.test.src tests with a strict __unit__.__build__ or
__hermetic__.__build__ suffix. This missed four categories of tests:
1. libc.test.include.* tests (e.g. isnan_test, signbit_test)
2. libc.test.integration.* tests (e.g. pthread, unistd, startup)
3. libc.test.src.* tests that have no __unit__/__hermetic__ marker (e.g.
errno_test, dirent_test, htonl)
4. libc.test.src.* tests with extra option suffixes between the type
marker and .__build__ (e.g. __unit__.__NO_FMA_OPT.__build__)
Wire up the two missing build dependencies so that check-libc-lit builds
include and integration tests before running them, and update
_isTestExecutable() to recognise all four patterns.
The pattern documentation was consolidated into the _isTestExecutable()
docstring, where it is next to the code it describes, to avoid the two
diverging in future.
Tested:
Compared the test count from a full `ninja check-libc` run (2765 tests)
against `llvm-lit --show-tests libc/test` after this change and
confirmed the counts match exactly.
The lit-based test execution added in c776a52fa263 did not propagate the
GPU loader executable to the lit site configuration. When building for
GPU targets, the loader (amdhsa-loader, nvptx-loader, or a
user-specified LIBC_GPU_LOADER_EXECUTABLE) was resolved into the
libc.utils.gpu.loader target but never passed through to the generated
lit.site.cfg.py.
Fix this by resolving the executable path from the libc.utils.gpu.loader
target property and including it in configure_lit_site_cfg's PATHS list.
In lit.site.cfg.py.in, if no explicit LIBC_TEST_CMD is set but a GPU
loader is present, construct libc_test_cmd from the loader path,
mirroring the logic in add_libc_hermetic() in LLVMLibCTestRules.cmake.
Tested:
* GPU build with LIBC_GPU_LOADER_EXECUTABLE set to /bin/echo used to
fail (tried to run the binary), now it works.
* Native compiler check-libc-lit continues to work after this change.