| Issue |
179800
|
| Summary |
[LTO][ThinLTO] Mixing of LTO and ThinLTO bitcode works in strange way
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
foxtran
|
Hello!
Considering the following C files:
- ftn.c:
```c
int ftn() {
return 77;
}
```
- main.c:
```c
int ftn();
int _start() {
return ftn();
}
```
And compiling them in different modes and checks using the following bash script:
```bash
#!/usr/bin/env bash
clang ftn.c -O3 -flto=thin -c -o ftn-thin.o
clang ftn.c -O3 -flto=full -c -o ftn-full.o
clang main.c -O3 -flto=thin -c -o main-thin.o
clang main.c -O3 -flto=full -c -o main-full.o
clang -fuse-ld=lld -nodefaultlibs -nostartfiles -flto=thin ftn-thin.o main-thin.o -o Sttt
clang -fuse-ld=lld -nodefaultlibs -nostartfiles -flto=thin ftn-thin.o main-full.o -o Sttf
clang -fuse-ld=lld -nodefaultlibs -nostartfiles -flto=thin ftn-full.o main-thin.o -o Stft
clang -fuse-ld=lld -nodefaultlibs -nostartfiles -flto=thin ftn-full.o main-full.o -o Stff
clang -fuse-ld=lld -nodefaultlibs -nostartfiles -flto=full ftn-thin.o main-thin.o -o Sftt
clang -fuse-ld=lld -nodefaultlibs -nostartfiles -flto=full ftn-thin.o main-full.o -o Sftf
clang -fuse-ld=lld -nodefaultlibs -nostartfiles -flto=full ftn-full.o main-thin.o -o Sfft
clang -fuse-ld=lld -nodefaultlibs -nostartfiles -flto=full ftn-full.o main-full.o -o Sfff
for filee in S*
do
objdump -S $filee > $filee.S
done
grep "ftn" S*.S -c
```
The output will be the following:
```
Sfff.S:0
Sfft.S:2
Sftf.S:2
Sftt.S:1
Stff.S:0
Stft.S:2
Sttf.S:2
Sttt.S:1
```
0 - `ftn` was inlined; `ftn` code is removed
1 - `ftn` was inlined, but `ftn` code is still presented
2 - `ftn` was not inlined
That means that:
| Binary name | LLD invocation | `ftn.c` mode | `main.c` mode | Resolution |
| :--- | :--- | :--- | :--- | --- |
| `Sfff` | `flto=full` | `flto=full` | `flto=full` | Works as expected |
| `Sfft` | `flto=full` | `flto=full` | `flto=thin` | LTO unexpectedly does not work: fullLTO does not need all information which is presented in ThinLTO bitcode |
| `Sftf` | `flto=full` | `flto=thin` | `flto=full` | LTO unexpectedly does not work: fullLTO does not need all information which is presented in ThinLTO bitcode |
| `Sftt` | `flto=full` | `flto=thin` | `flto=thin` | Works as expected, but it needs `-Wl,--gc-sections` for removing unused symbols |
| `Stff` | `flto=thin` | `flto=full` | `flto=full` | Unexpectedly works. ThinLTO does not have enough information |
| `Stft` | `flto=thin` | `flto=full` | `flto=thin` | LTO does not work as expected. ThinLTO does not have enough information from `main.c` |
| `Sttf` | `flto=thin` | `flto=thin` | `flto=full` | LTO does not work as expected. ThinLTO does not have enough information from `ftn.c` |
| `Sttt` | `flto=thin` | `flto=thin` | `flto=thin` | Works as expected, but it needs `-Wl,--gc-sections` for removing unused symbols |
So, my questions:
- Why linker with `-flto=thin` is able to work with fullLTO bitcode?
- Why linker with `-flto=full` is not able to use ThinLTO bitcode together with FatLTO bitcode?
- Why linker with `-flto=full` needs `-Wl,--gc-sections` to clean unused symbols in the case of `Sftt` binary?
Tested with clang with the most recent commits:
```
clang version 23.0.0git (https://github.com/llvm/llvm-project.git 2e429f7e1f5b490a703de4cf06ef65eed784f7ab)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /tmp/llvm/llvm-project/install/bin
Build config: +assertions
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs