-
Notifications
You must be signed in to change notification settings - Fork 15.1k
Open
Labels
Description
-mfs-split-ehcode has an unfortunate side effect of breaking linker garbage collection enabled with --gc-sections.
Here is a simple example:
$ cat main.cc
extern void bar();
void foo() {
try {
bar();
} catch (...) {
bar();
}
bar();
}
int main() {
return 0;
}
$ cat bar.cc
void bar() {}
# Without Splitter: foo removed successfully
$ clang++ main.cc bar.cc -fuse-ld=lld -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--print-gc-sections |& grep foo
removing unused section /tmp/main-789e6f.o:(.text)
removing unused section /tmp/main-789e6f.o:(.text._Z3foov)
removing unused section /tmp/main-789e6f.o:(.text.__clang_call_terminate)
# With Splitter: foo NOT removed
$ clang++ main.cc bar.cc -fuse-ld=lld -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--print-gc-sections -mllvm -enable-split-machine-functions -mllvm -mfs-split-ehcode |& grep foo
The reason for this is the following liveness chain:
- exception table
.gcc_except_table._Z3foovreferencesfoo.cold:and is a GC root in Lld linkerRelocation section '.rela.gcc_except_table._Z3foov' at offset 0x4e8 contains 2 entries: Offset Info Type Symbol's Value Symbol's Name + Addend 0000000000000001 0000000300000018 R_X86_64_PC64 0000000000000000 .text.split._Z3foov + 0 0000000000000019 0000000300000018 R_X86_64_PC64 0000000000000000 .text.split._Z3foov + 0 foo.coldreferencesfoo:Relocation section '.rela.text.split._Z3foov' at offset 0x440 contains 7 entries: Offset Info Type Symbol's Value Symbol's Name + Addend ... 0000000000000021 0000000200000004 R_X86_64_PLT32 0000000000000000 .text._Z3foov + 9 ...
Thus foo (and foo.cold), although being clearly dead, end up in final executable.
This issue was found when investigating catastrophic code sizes increases in Rust projects under -enable-split-machine-functions -mfs-split-ehcode (10% tokio, 2x meilisearch, etc.). -basic-block-sections may have the same problem (I didn't check).
LLVM was build via
cmake -G Ninja "-DLLVM_ENABLE_ASSERTIONS=ON" "-DLLVM_UNREACHABLE_OPTIMIZE=OFF" "-DLLVM_ENABLE_PLUGINS=OFF" "-DLLVM_TARGETS_TO_BUILD=X86" "-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=" "-DLLVM_INCLUDE_EXAMPLES=OFF" "-DLLVM_INCLUDE_DOCS=OFF" "-DLLVM_INCLUDE_BENCHMARKS=OFF" "-DLLVM_INCLUDE_TESTS=OFF" "-DLLVM_ENABLE_TERMINFO=OFF" "-DLLVM_ENABLE_LIBEDIT=OFF" "-DLLVM_ENABLE_BINDINGS=OFF" "-DLLVM_ENABLE_Z3_SOLVER=OFF" "-DLLVM_TARGET_ARCH=x86_64" "-DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-unknown-linux-gnu" "-DLLVM_ENABLE_LIBXML2=OFF" "-DCMAKE_CXX_COMPILER=c++" "-DLLVM_ENABLE_ZSTD=OFF" "-DCMAKE_BUILD_TYPE=Release" -DLLVM_ENABLE_PROJECTS='clang;lld' ../llvm
from ToT:
commit e246fffb253c3ed9a2c0b4a71ef33d97c7b5629c (HEAD -> main, origin/main, origin/HEAD)
Author: Congzhe <[email protected]>
Date: Sun Oct 26 00:39:49 2025 -0400
Reland "[InstructionSimplify] Enhance simplifySelectInst() (#163453)" (#164694)