30 Commits

Author SHA1 Message Date
Louis Dionne
09d7b890e0
[libc++] Add a thread-safe version of std::lgamma in the dylib (#153631)
Libc++ currently redeclares ::lgamma_r on platforms that provide it.
This causes issues when building with modules, and redeclaring functions
provided by another library (here the C library) is bad hygiene.

Instead, use an asm declaration to call the right function without
having to redeclare it.
2026-02-25 13:46:51 -05:00
Louis Dionne
53ad9cdc32 [libc++] Fix typo in math special functions
Extracted from #156270

Co-Authored-by: Austin Jiang <austinjiangboyu@gmail.com>
2026-01-13 08:47:09 -05:00
Nikolas Klauser
bb1158f14a
[libc++] Fix LLVM 22 TODOs (#153367)
We've upgraded to LLVM 22 now, so we can remove a bunch of TODOs.
2025-10-30 10:34:41 +01:00
Nikolas Klauser
34d4f0c136
[libc++][NFC] Use llvm.org/PR to link to bug reports (#156288)
We've built up quite a few links directly to github within the code
base. We should instead use `llvm.org/PR<issue-number>` to link to bugs,
since that is resilient to the bug tracker changing in the future. This
is especially relevant for tests linking to bugs, since they will
probably be there for decades to come. A nice side effect is that these
links are significantly shorter than the GH links, making them much less
of an eyesore.

This patch also replaces a few links that linked to the old bugzilla
instance on llvm.org.
2025-09-04 09:20:02 +02:00
A. Jiang
3bdfca58a6
[libc++] Workaround for a bug of overloads in MS UCRT's <math.h> (#149234)
MS UCRT seems confused on the status of LWG1327, and still provides
pre-LWG1327 overload set the related math functions, which can't handle
integer types as required. It is probably that UCRT won't fixed this in
a near future, per
https://developercommunity.visualstudio.com/t/10294165.

Before C++20, libc++ worked around this bug by relying on
`-fdelayed-template-parsing`. However, this non-conforming option is off
by default since C++20. I think we should use `requires` instead.

---------

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2025-08-05 17:47:11 +08:00
Steffen Larsen
09cc8eaf1b
[libc++] Fix return type of ilogb(double) (#150374)
This commit addresses a seemingly unintentional return type of the ilogb
overload taking a double. Currently it returns double, while it is
supposed to return int.

The return types seems to be covered by libcxx/test/std/numerics/c.math/cmath.pass.cpp,
but the issue would only show up if we tested with a libc that doesn't
provide the ilogb(double) overload, which we don't.
2025-07-31 15:25:18 -04:00
Nikolas Klauser
584cc37687
[libc++] Move std::abs into __math/abs.h (#139586)
`template <class = int>` is also added to our implementations to avoid
an ambiguity between the libc's version and our version when both are
visible.

This avoids including `<stdlib.h>` in `<math.h>`.
2025-06-19 10:37:18 +02:00
Nikolas Klauser
948bffa951
[libc++] Simplify __promote (#136101)
This avoids instantiating an extra class for every variant `__promote`
is used in.
2025-05-08 16:48:57 -04:00
Nikolas Klauser
66531c998a
[libc++] Remove one of the std::signbit overloads (#130505)
We'e specialized `std::signbit` for signed and unsigned integral types
seperately, even though the optimizer can trivially figure out that
`unsigned_value < 0` always false is. This patch removes the
specialization, since there is really not much of a benefit to it.
2025-03-24 07:30:45 +01:00
Nikolas Klauser
17e0686ab1
[libc++][NFC] Use [[__nodiscard__]] unconditionally (#80454)
`__has_cpp_attribute(__nodiscard__)` is always true now, so we might as
well replace `_LIBCPP_NODISCARD`. It's one less macro that can result in
bad diagnostics.
2024-09-12 21:18:43 +02:00
Robin Caloudis
c6b2aa1896
[libc++][math] Provide overloads for cv-unqualified floating point types for std::signbit (#106566)
## Why
Following up on https://github.com/llvm/llvm-project/pull/105946, this
patch provides the floating point overloads for `std::signbit` as
defined by
[P0533R9](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0533r9.pdf).

## What
* Test and add overloads for cv-unqualified floating point types
* Remove constrained overload as it is not needed anymore
* Make use of `template<class = void>` as the universal C runtime (UCRT)
needed for Clang-Cl comes with overloads for all cv-unqualified floating
point types (float, double, long double) for `std::signbit()` by itself
[in the
WinSDK](e012b29924/generation/WinSDK/RecompiledIdlHeaders/ucrt/corecrt_math.h (L309-L322)).
In a certain way, this can be seen as a deviation from the C standard.
We need to work around it as the compilation would otherwise error out
due to duplicated definitions.
2024-09-12 21:14:00 +02:00
Louis Dionne
eb0f12188a
[libc++][modules] Tweak a few includes (#107467)
Add a few missing includes, remove two unnecessary ones and use
__cstddef/size_t.h instead of <cstddef> in a few places. This is a
collection of miscellaneous findings that collectively unblock other
modularization patches.
2024-09-06 12:10:04 -04:00
Robin Caloudis
1a1264726d
[libc++][math] Add constexpr for std::signbit() (#105946)
## Why
Since 18th of August, the floating point comparison builtin
``__builtin_signbit`` is available in Clang as constant expression
(https://github.com/llvm/llvm-project/pull/94118).

## What
* Implement `constexpr` for `std::signbit()` as defined by
[P0533R9](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0533r9.pdf)
(new C++23 feature)
* Restrict execution of tests to tip-of-trunk Clang as builtin is not
yet available (note that builtin is available in GCC)
2024-09-05 15:44:16 +02:00
Louis Dionne
23f6c3370b
[libc++][modules] Remove dependency on __algorithm/max from hypot.h (#107150)
That dependency was added recently when we made improvements to
std::hypot, but that resulted in `__math` depending on `__algorithm`,
which is a very heavyweight module. This patch uses `__math::fmax`
instead.
2024-09-04 16:39:09 -04:00
Louis Dionne
d9019d478d
[libc++] Remove unused pair.h include from hypot.h (#106798)
This was added in #100820 by mistake since the final version of that PR
didn't depend on std::pair anymore.
2024-09-04 11:17:32 -04:00
Robin Caloudis
2f0661c211
[libc++][math] Remove constrained overloads of std::{isnan, isinf, isfinite} (#106224)
## Why
Since https://github.com/llvm/llvm-project/pull/98841 and
https://github.com/llvm/llvm-project/pull/98952, the constrained
overloads are unused and not needed anymore as we added explicit
overloads for all floating point types. I forgot to remove them in the
mentioned PRs.

## What
Remove them.
2024-08-28 12:40:26 +02:00
Robin Caloudis
866bec7d3f
[libc++][math] Provide overloads for cv-unqualified floating point types for std::isnormal (#104773)
## Why
Currently, the following does not work when compiled with clang:

```c++
#include <cmath>

struct ConvertibleToFloat {
    operator float();
};

bool test(ConvertibleToFloat x) {
    return std::isnormal(x);
}
```
See https://godbolt.org/z/5bos8v67T for differences with respect to
msvc, gcc or icx. It fails for `float`, `double` and `long double` (all
cv-unqualified floating-point types).

## What
Test and provide overloads as expected by the ISO C++ standard. The
classification/comparison function `isnormal` is defined since C++11
until C++23 as
```c++
bool isnormal( float num );
bool isnormal( double num );
bool isnormal( long double num );
```
and since C++23 as
```c++
constexpr bool isnormal( /* floating-point-type */ num );
```
for which "the library provides overloads for all cv-unqualified
floating-point types as the type of the parameter num". See §28.7.1/1 in
the [ISO C++
standard](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4950.pdf)
or check
[cppreference](https://en.cppreference.com/w/cpp/numeric/math/isnormal).
2024-08-28 10:34:47 +02:00
Robin Caloudis
2fe59d5259
[libc++][math] Fix acceptance of convertible types in std::isnan() and std::isinf() (#98952)
Following up on https://github.com/llvm/llvm-project/pull/98841.

Changes:
- Properly test convertible types for `std::isnan()` and `std::inf()`
- Tighten conditional in `cmath.pass.cpp` (Find insights on `_LIBCPP_PREFERRED_OVERLOAD` below)
- Tighten preprocessor guard in `traits.h`

Insights into why `_LIBCPP_PREFERRED_OVERLOAD` is needed:

(i) When libc++ is layered on top of glibc on Linux, glibc's `math.h` is
    included. When compiling with `-std=c++03`, this header brings the
    function declaration of `isinf(double)` [1] and `isnan(double)` [2]
    into scope. This differs from the C99 Standard as only the macros
    `#define isnan(arg)` and `#define isinf(arg)` are expected.

    Therefore, libc++ needs to respect the presense of the `double` overload
    and cannot redefine it as it will conflict with the declaration already
    in scope. For `-std=c++11` and beyond this issue is fixed, as glibc
    guards both the `isinf` and `isnan` by preprocessor macros.

(ii) When libc++ is layered on top of Bionic's libc, `math.h` exposes a
     function prototype for `isinf(double)` with return type `int`. This
     function prototype in Bionic's libc is not guarded by any preprocessor
     macros [3].

`_LIBCPP_PREFERRED_OVERLOAD` specifies that a given overload is a better match
than an otherwise equally good function declaration. This is implemented in
modern versions of Clang via `__attribute__((__enable_if__))`, and not elsewhere.
See [4] for details. We use `_LIBCPP_PREFERRED_OVERLOAD` to define overloads in
the global namespace that displace the overloads provided by the C
libraries mentioned above.

[1]: fe94080875/math/bits/mathcalls.h (L185-L194)
[2]: fe94080875/math/bits/mathcalls.h (L222-L231)
[3]: https://cs.android.com/android/platform/superproject/+/master:bionic/libc/include/math.h;l=322-323;drc=master?hl=fr-BE%22https:%2F%2Fsupport.google.com%2Fmerchants%2Fanswer%2F188494%5C%22%22https:%2F%2Fsupport.google.com%2Fmerchants%2Fanswer%2F188494%5C%22
[4]: 5fd17ab1b0
2024-08-16 11:18:49 -04:00
PaulXiCao
72825fde03
[libc++][math] Fix undue overflowing of std::hypot(x,y,z) (#100820)
This is in relation to mr #93350. It was merged to main, but reverted
because of failing sanitizer builds on PowerPC.

The fix includes replacing the hard-coded threshold constants (e.g.
`__overflow_threshold`) for different floating-point sizes by a general
computation using `std::ldexp`. Thus, it should now work for all architectures.
This has the drawback of not being `constexpr` anymore as `std::ldexp`
is not implemented as `constexpr` (even though the standard mandates it
for C++23).

Closes #92782
2024-08-05 16:08:47 -04:00
Mitch Phillips
1031335f2e Revert "[libc++][math] Fix undue overflowing of std::hypot(x,y,z) (#93350)"
This reverts commit 9628777479a970db5d0c2d0b456dac6633864760.

More details in https://github.com/llvm/llvm-project/pull/93350, but
this broke the PowerPC sanitizer bots.
2024-07-24 13:18:27 +02:00
PaulXiCao
9628777479
[libc++][math] Fix undue overflowing of std::hypot(x,y,z) (#93350)
The 3-dimentionsional `std::hypot(x,y,z)` was sub-optimally implemented.
This lead to possible over-/underflows in (intermediate) results which
can be circumvented by this proposed change.

The idea is to to scale the arguments (see linked issue for full
discussion).

Tests have been added for problematic over- and underflows.

Closes #92782
2024-07-23 11:11:44 -04:00
PaulXiCao
af0d731b12
[libc++][math] Mathematical Special Functions: Hermite Polynomial (#89982)
Implementing the Hermite polynomials which are part of C++17's
mathematical special functions. The goal is to get early feedback which
will make implementing the other functions easier. Integration of
functions in chunks (e.g. `std::hermite` at first, then `std::laguerre`,
etc.) might make sense as well (also see note on boost.math below).

I started out from this abandoned merge request:
https://reviews.llvm.org/D58876 .

The C++23 standard defines them in-terms of `/* floating-point type */`
arguments. I have not looked into that.

Note, there is still an ongoing discussion on discourse whether
importing boost.math is an option.
2024-07-20 17:50:05 +02:00
Robin Caloudis
7f2bd53b14
[libc++] Fix acceptance of convertible-to-{float,double,long double} in std::isfinite() (#98841)
Closes https://github.com/llvm/llvm-project/issues/98816.
2024-07-18 09:01:09 -04:00
Nikolas Klauser
6b4b29f859
[libc++][NFC] Remove unnecessary parens in static_asserts (#95605)
These were required a long time ago due to `static_assert` not actually
being available in C++03. Now `static_assert` is simply mapped to
`_Static_assert` in C++03, making the additional parens unnecessary.
2024-06-18 10:45:30 +02:00
Nikolas Klauser
83bc7b5771
[libc++] Remove _LIBCPP_DISABLE_NODISCARD_EXTENSIONS and refactor the tests (#87094)
This also adds a few tests that were missing.
2024-04-22 22:13:58 +02:00
Nikolas Klauser
dcdcc7c804 [libc++][NFC] Replace typedefs with using in the math headers
Reviewed By: #libc, Mordante, ldionne

Spies: Mordante, libcxx-commits

Differential Revision: https://reviews.llvm.org/D155382
2023-08-03 08:51:50 -07:00
Nikolas Klauser
f3589d25fe [libc++][NFC] Refactor the enable_ifs in the math headers
Reviewed By: #libc, Mordante

Spies: Mordante, libcxx-commits

Differential Revision: https://reviews.llvm.org/D155261
2023-08-02 10:03:32 -07:00
Nikolas Klauser
0e4d812f3e [libc++][NFC] Format math headers
Reviewed By: #libc, Mordante

Spies: arichardson, Mordante, libcxx-commits

Differential Revision: https://reviews.llvm.org/D155260
2023-07-31 17:19:49 -07:00
Nikolas Klauser
404d31196f [libc++][NFC] Remove std:: qualifications from math headers
Reviewed By: #libc, Mordante

Spies: Mordante, libcxx-commits

Differential Revision: https://reviews.llvm.org/D155259
2023-07-31 17:19:44 -07:00
Nikolas Klauser
6553608aca [libc++] Granulaize math.h and move the functions to std::__math
Reviewed By: #libc, Mordante

Spies: Mordante, arichardson, libcxx-commits

Differential Revision: https://reviews.llvm.org/D155258
2023-07-31 17:19:39 -07:00