| Issue |
165139
|
| Summary |
-mfs-split-ehcode breaks linker garbage collection
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
yugr
|
`-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._Z3foov` references `foo.cold`:
```
Relocation 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
```
and is a [GC root in Lld linker](https://github.com/llvm/llvm-project/blob/3b299af92383cb7558224482ccfa714f0162f772/lld/ELF/MarkLive.cpp#L378)
- `foo.cold` references `foo`:
```
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.).
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)
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs