Skip to content

Update libcxx and libcxxabi to LLVM 20.1.4 #24346

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

aheejin
Copy link
Member

@aheejin aheejin commented May 16, 2025

This updates libcxx and libcxxabi to LLVM 20.1.4:
https://github.com/llvm/llvm-project/releases/tag/llvmorg-20.1.4

Before going into each additional change of the PR, these are some noteworthy changes from this LLVM release:


Additional changes:

  • Copy vendor/llvm/default_assertion_handler.in to __assertion_handler: aa53648
    Our previous __assertion_handler was copied from libcxx/vendor/llvm/default_assertion_handler.in. This updates our __assertion_handler to the new libcxx/vendor/llvm/default_assertion_handler.in. For what this file is, see the PR description of Update libcxx and libcxxabi to LLVM 19.1.4 #22994, with which the file was added.

  • Remove libcxx/include/__cxx03 directory: d646f6b
    As I described in "Freezing C++ headers" above, C++03 headers were copied to include/cxx03 to be "frozen". But by not defining _LIBCPP_USE_FROZEN_CXX03_HEADERS we can still use the main headers. This new __cxx03 header directory is almost 10M and we are not using it in this update, this deletes it.

  • Define more variables in __config_site: 9912236
    libcxx decides to almost all configuration macros to be defined. So before it tested whether a macro was defined/undefined, and now it assumes it is defined and tests whether its value is 1/0.

    Before [libc++] Refactor the configuration macros to being always defined llvm/llvm-project#112094 _config_site.in used to use #cmakedefine, which only defined variables when they were enabled, but now it uses #cmakedefine01, which always defines variables and assigns 1 or 0 depending on whether the feature is enabled.

    So this change adds #define to each variable that _config_site.in has an entry of. The value assigned is 1 if it was defined in our previous Emscripten environment and 0 if not.

  • Fix Emscripten's locale: 2ae01b0
    Before, the code was like

    #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__)
    # include <xlocale.h>
    #elif defined(_LIBCPP_MSVCRT_LIKE)
    # include <__locale_dir/locale_base_api/win32.h>
    #elif defined(_AIX) || defined(__MVS__)
    # include <__locale_dir/locale_base_api/ibm.h>
    #elif defined(__ANDROID__)
    # include <__locale_dir/locale_base_api/android.h>
    #elif defined(__sun__)
    # include <__locale_dir/locale_base_api/solaris.h>
    #elif defined(_NEWLIB_VERSION)
    # include <__locale_dir/locale_base_api/newlib.h>
    #elif defined(__OpenBSD__)
    # include <__locale_dir/locale_base_api/openbsd.h>
    #elif defined(__Fuchsia__)
    # include <__locale_dir/locale_base_api/fuchsia.h>
    #elif defined(__wasi__) || defined(_LIBCPP_HAS_MUSL_LIBC)
    # include <__locale_dir/locale_base_api/musl.h>
    #endif

    But now they are divided into two parts, one using the new API and the other using old. See "Locale API reimplementation" above.
    https://github.com/llvm/llvm-project/blob/ec28b8f9cc7f2ac187d8a617a6d08d5e56f9120e/libcxx/include/__locale_dir/locale_base_api.h#L116-L138
    This adds Emscripten in the beginning of the "old" API list. (This has to be the beginning; see Fix compat between libc++ and emscripten's xlocale.h #23414)

  • Import libc headers used by libcxx: 12a4ee4, 12a4ee4 and 43c8ce4
    This imports a part of libc headers into system/lib/llvm-libc. The imported directories are:

  • std::uncaught_exception -> std::uncaught_exceptions: 1bf4e78
    std::uncaught_exception has been deprecated in C++17, so it generates a warning (which we treat as an error). Replaced it with std::uncaught_exceptions, which returns the number of uncaught exceptions (but can still be used as a boolean in the test).

aheejin added 16 commits May 14, 2025 22:20
Our prevous `__assertion_handler` was copied from
`libcxx/vendor/llvm/default_assertion_handler.in`. This updates out
`__assertion_handler` to the new
`libcxx/vendor/llvm/default_assertion_handler.in`. For what this file
is, see the PR description of emscripten-core#22994, with which the file was added.
As I described in "Freezing C++ headers" above, C++03 headers were
copied to `include/cxx03` to be "frozen". But by not defining
`_LIBCPP_USE_FROZEN_CXX03_HEADERS` we can still use the main headers.
This new `__cxx03` header directory is almost 10M and we are not using
it in this update, this deletes it.
libcxx decides to almost all configuration macros to be defined. So
before it tested whether a macro was defined/undefined, and now it
assumes it is defined and tests whether its value is 1/0.

Before llvm/llvm-project#112094
`_config_site.in` used to use `#cmakedefine`, which only defined
variables when they were enabled, but now it uses `#cmakedefine01`,
which always defines variables and assigns 1 or 0 depending on whether
the feature is enabled.

So this change adds `#define` to each variable that `_config_site.in`
has an entry of. The value assigned is 1 if it was defined in our
previous Emscripten environment and 0 if not.
Before, the code was like
https://github.com/emscripten-core/emscripten/blob/dc1abd514b1bade135a01a4453a9ff6def0793b6/system/lib/libcxx/include/__locale_dir/locale_base_api.h#L12-L30

But now they are divided into two parts, one using the new API and the
other using old. See "Locale API reimplementation" above.
https://github.com/llvm/llvm-project/blob/ec28b8f9cc7f2ac187d8a617a6d08d5e56f9120e/libcxx/include/__locale_dir/locale_base_api.h#L116-L138

This adds Emscripten in the beginning of the "old" API list. (This has
to be the beginning; see emscripten-core#23414)
This imports a part of libc headers into `system/lib/llvm-libc`. The
imported directories are:
- `libc/shared`
- `libc/src/__support`
- `libc/include/llvm-libc-macros`
- `libc/include/llvm-libc-types`
- `libc/hdr`
See "sharing of headers between libc+ and libc" above for details.
LLVM 20 release contains a bug that it one of the headers in
`libc/src/__support` directory includes a header from `libc/src/errno`,
which is not one of the header directories that are meant to be
included:
https://github.com/llvm/llvm-project/blob/ec28b8f9cc7f2ac187d8a617a6d08d5e56f9120e/libc/src/__support/str_to_float.h#L34

I was told
(llvm/llvm-project#91651 (comment))
this was a bug that was fixed in
llvm/llvm-project#133999. Whether this fix will
be backported to later version of LLVM 20 release is unclear. To avoid
importing files from `libc/src`, this applies the fix here as well.
`std::uncaught_exception` has been deprecated in C++17, so it generates
a warning (which we treat as an error). Replaced it with
`std::uncaught_exceptions`, which returns the number of uncaught
exceptions (but can still be used as a boolean in the test).
This rebaselines
other.test_codesize_files_wasmfs
other.test_codesize_cxx_except
other.test_codesize_cxx_mangle

These have `*.imports` or `*.funcs` so `rebaseline_tests.py` cannot
handle them. So this rebaselines them manually.
This is an automatic change generated by tools/maint/rebaseline_tests.py.

The following (9) test expectation files were updated by
running the tests with `--rebaseline`:

```
code_size/embind_hello_wasm.json: 16727 => 16673 [-54 bytes / -0.32%]
code_size/embind_val_wasm.json: 16377 => 16323 [-54 bytes / -0.33%]
other/codesize/test_codesize_cxx_ctors1.size: 129217 => 129654 [+437 bytes / +0.34%]
other/codesize/test_codesize_cxx_ctors2.size: 128610 => 129039 [+429 bytes / +0.33%]
other/codesize/test_codesize_cxx_except_wasm.size: 144593 => 144770 [+177 bytes / +0.12%]
other/codesize/test_codesize_cxx_except_wasm_legacy.size: 142168 => 142360 [+192 bytes / +0.14%]
other/codesize/test_codesize_cxx_lto.size: 121938 => 121882 [-56 bytes / -0.05%]
other/codesize/test_codesize_cxx_noexcept.size: 131780 => 132027 [+247 bytes / +0.19%]
other/codesize/test_codesize_cxx_wasmfs.size: 169161 => 169897 [+736 bytes / +0.44%]

Average change: +0.09% (-0.33% - +0.44%)
```
@aheejin aheejin marked this pull request as ready for review May 16, 2025 07:48
@aheejin
Copy link
Member Author

aheejin commented May 16, 2025

The only failing test is instance.test_async_hello_v8 and this fails for me locally even in the main branch, saying

emcc: error: MODULARIZE=instance is not compatible with -sASYNCIFY=1

So I think this error is not related.

@aheejin aheejin requested a review from sbc100 May 16, 2025 17:05
@sbc100
Copy link
Collaborator

sbc100 commented May 16, 2025

Indeed instance.test_async_hello_v8 is unrelated.

Copy link
Collaborator

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a new update script or add llvm-libc to system/lib/update_libcxx.py?

@aheejin
Copy link
Member Author

aheejin commented May 16, 2025

Do we need a new update script or add llvm-libc to system/lib/update_libcxx.py?

Will do that in a follow-up.

@sbc100
Copy link
Collaborator

sbc100 commented May 16, 2025

After this we still have the compiler-rt changes right? Do you think its worth holding off making a release until that is done? (I was hoping to make a release soon).

@aheejin
Copy link
Member Author

aheejin commented May 16, 2025

I think maybe even for this PR it's better to wait for at least several days to see whether the waterfall is stable, because this is also a big change. How about doing the release now (or in a few days) and I land this (and compiler-rt) later?

@sbc100
Copy link
Collaborator

sbc100 commented May 16, 2025

Yes, I actually think it might be a good to get a release out once I land #24288.. then we can land this after the release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants