[Inliner] Inlining of some functions in comdats leads to linking errors
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
Currently some functions are inlined in a way that will retain references to discarded sections, leading to linking errors.
This primarily happens with comdats that contain symbols with local linkage:
https://godbolt.org/z/1x6hPces1
```llvm
$f = comdat any
@glob = private unnamed_addr constant i8 zeroinitializer, comdat($f)
define ptr @g() {
%1 = call ptr @f()
ret ptr %1
}
define linkonce_odr ptr @f() comdat {
ret ptr @glob
}
```
`f` gets inlined into `g` so that `g` contains a direct reference to `glob`.
If the comdat `$f` is discarded, `g` keeps the reference to the now discarded `glob`, which can't have a replacement from the non-discarded comdat as `glob` is local.
Somewhat related, what if COMDATs from different modules contain different sets of symbols?
https://godbolt.org/z/dKsTMMqxx
```llvm
$f = comdat any
define weak ptr @g(i32 %x) comdat($f) {
ret ptr null
}
define weak_odr ptr @f(i32 %x) comdat {
%2 = call ptr @g(i32 %x)
ret ptr %2
}
define ptr @test(i32 %x) {
%2 = call ptr @f(i32 %x)
ret ptr %2
}
```
Here, a direct call to `g` gets inlined into `test`, but if the `$f` comdat of another module does not contain `g` and the `g` of the current module gets dropped, we get the same problem with references to discarded symbols.
Is the requirement that the set of exported symbols of each comdat with the same key should contain the same symbols? If so, maybe that should get documented.
Contributor guide
Assessment
This issue has not been assessed yet.