Repository navigation
🐛 Avoid lambdas in comparison and scaling for LLVM 23 LTO - #6
Merged
Merged
Conversation
With LLVM 23 (clang 23.1.2), full LTO with -g produces a module that
fails verification ("invalid retained nodes, retained node does not
belong to subprogram") when a function template holding a lambda is
instantiated both in a module unit and in a TU that imports it. ld.lld
aborts the link; Apple's ld64 warns and strips the debug info. LLVM
22.1.8 is not affected.
The lambdas in the framework's runtime paths become named function
templates, so there is no local type for the linker to merge:
- compare_in_common_type(): the fallback comparison is now
compare_in_common_type_fallback(). The comment above it records the
details for upstream.
- div_round(): the remainder is now div_remainder().
- scale_impl(): the floating-point scaling is now scale_fp_for().
libhal hit the first one on Linux x86_64 and arm64 (-std=c++23
-stdlib=libc++ -flto -g -Os -fsanitize=address, ld.lld): its spi module
and that module's unit test both compared quantity<si::hertz, unsigned>
values.
Verified by building libhal against this change with the hertz
comparison put back: the verifier error is gone and its tests pass. The
mp-units tests pass in header mode with LLVM 23 (build:all, 64/64).
This was referenced Oct 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces the lambdas in the framework's runtime comparison and scaling paths with named function templates, to work around an LLVM 23 LTO bug.
With clang 23.1.2, full LTO with
-gproduces a module that fails verification when a function template holding a lambda is instantiated both in a module unit and in a TU that imports it:ld.lldaborts the link; Apple's ld64 warns and strips the debug info. LLVM 22.1.8 is not affected. A named function has no local type for the linker to merge, so it avoids the bug. Details and a minimal reproducer are in libhal/llvm-toolchain#59.Changes:
compare_in_common_type(): the fallback comparison is nowcompare_in_common_type_fallback(). It is still called from both branches, so there is no fallthroughreturnfor MSVC Debug C4702. The comment above it is a note for the mp-units maintainers.div_round(): the remainder is nowdiv_remainder().scale_impl(): the floating-point scaling is nowscale_fp_for().libhal hit the first one on Linux CI (libhal/libhal#255): its spi module and that module's unit test both compared
quantity<si::hertz, unsigned>values, and linking the test aborted.Verified locally with LLVM 23.1.2 on macOS:
conan buildwithuser.mp-units.build:all=Truein header mode: the static tests and header-set checks build, and 64/64 runtime tests pass.Once merged, this needs a new
@libhalrelease for libhal to pick it up.