ld.lld hangs when building Linux kernel with full LTO after recent flatten change
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
After commit [8062e82db89f](https://github.com/llvm/llvm-project/commit/8062e82db89f12d90e8c331db217904689b87947) ("[Clang] Emit LLVM flatten attribute instead of per-callsite alwaysinline (#188615)", 2026-04-27), I am seeing what appears to be an infinite loop when building the Linux kernel with full LTO (`CONFIG_LTO_CLANG_FULL=y`). So far, I have managed to reduce the reproducer down to just a couple of configurations on top of the kernel's `allnoconfig` target, which turns all possible configurations to `n`, so it is a pretty minimal build target.
```
$ curl -LSs https://cdn.kernel.org/pub/linux/kernel/v7.x/linux-7.0.3.tar.xz | tar -xJf -
$ cd linux-7.0.3
$ printf 'CONFIG_%s\n' LTO_NONE=n LTO_CLANG_FULL=y SMP=y >allno.config
$ cat allno.config
CONFIG_LTO_NONE=n
CONFIG_LTO_CLANG_FULL=y
CONFIG_SMP=y
# If problematic LLVM is in PATH, use LLVM=1. If not, use LLVM=/bin/
# See https://docs.kernel.org/kbuild/llvm.html#the-llvm-argument for more info
$ make -kj"$(nproc)" ARCH=x86_64 KCONFIG_ALLCONFIG=1 LLVM=1 O=build mrproper allnoconfig vmlinux
...
AR fs/proc/built-in.a
AR fs/built-in.a
CC arch/x86/kernel/cpu/capflags.o
AR arch/x86/kernel/cpu/built-in.a
AR arch/x86/kernel/built-in.a
AR arch/x86/built-in.a
AR built-in.a
AR vmlinux.a
GEN .tmp_initcalls.lds
LD vmlinux.o
```
Checking `ps` in a separate terminal instance shows `ld.lld` spinning for over an hour.
```
$ ps -p (pidof ld.lld) -o etime
ELAPSED
01:15:27
```
I had let a build spin overnight to see if it would ever finish but `ld.lld` ran for over twelve hours without exiting in that case. At the parent commit, the above reproducer completes fine.
```
AR vmlinux.a
GEN .tmp_initcalls.lds
LD vmlinux.o
MODPOST vmlinux.symvers
CC .vmlinux.export.o
UPD include/generated/utsversion.h
CC init/version-timestamp.o
KSYMS .tmp_vmlinux0.kallsyms.S
AS .tmp_vmlinux0.kallsyms.o
LD .tmp_vmlinux1
NM .tmp_vmlinux1.syms
KSYMS .tmp_vmlinux1.kallsyms.S
AS .tmp_vmlinux1.kallsyms.o
LD .tmp_vmlinux2
NM .tmp_vmlinux2.syms
KSYMS .tmp_vmlinux2.kallsyms.S
AS .tmp_vmlinux2.kallsyms.o
LD vmlinux.unstripped
NM System.map
SORTTAB vmlinux.unstripped
GEN modules.builtin.modinfo
OBJCOPY vmlinux
GEN modules.builtin
```
This configuration builds in less than a minute on this machine.
```
Benchmark 1: LLVM @ 98fe008141a1fd30eb8cb576c6385a67cf45d111
Time (mean ± σ): 51.953 s ± 0.154 s [User: 448.276 s, System: 32.952 s]
Range (min … max): 51.786 s … 52.195 s 5 runs
```
As far as I can tell, this is not resolved with the forward fix in #194485. I will see if I can try and tease out a slimmer reproducer from the kernel source but I wanted to dump what I had so far in case anything sticks out (and getting reproducers with LTO is always fun).
cc @grigorypas
```
# bad: [bcbad84a7c56c99c0d628e2b24fac856c87bb98a] [clang][bytecode] Only revisit C variables with valid initializers (#194881)
# good: [2428fbb613be0f2b4468cfa26908186e097262c7] [NFC][ThinLTO] Remove JumpTableToSwitchPass from the test (#194103)
git bisect start 'bcbad84a7c56c99c0d628e2b24fac856c87bb98a' '2428fbb613be0f2b4468cfa26908186e097262c7'
# bad: [61760fd348eea42f3b640e569aaca0489f80f7aa] [AArch64][GlobalISel] Update fp legalization mir tests. NFC (#194561)
git bisect bad 61760fd348eea42f3b640e569aaca0489f80f7aa
# good: [889708eed861b4218fda5a085b47f37b6b73b739] [CIR][OpenMP] Enable emission of target functions (#193204)
git bisect good 889708eed861b4218fda5a085b47f37b6b73b739
# good: [5ea9d1045d4cb641d05e5dc6c90b2659a48ed543] [MCP][NFC] Add Cost modelling for EliminateSpillageCopies (#193905)
git bisect good 5ea9d1045d4cb641d05e5dc6c90b2659a48ed543
# bad: [043e778f85f60b654547f2104bca32fdbed2eafd] lldb] Fix two issues causing TestEvents.py flakiness (#194438)
git bisect bad 043e778f85f60b654547f2104bca32fdbed2eafd
# bad: [7f6697b824d7d1c9b732f6c5cff37f2b1471cbd6] fix preserve_none in X86 backend (#192300)
git bisect bad 7f6697b824d7d1c9b732f6c5cff37f2b1471cbd6
# good: [2962f641eaf73a1ecade4c6fa221606e6326041b] Allow DIBasicType (and others) to have a scope and location (#190217)
git bisect good 2962f641eaf73a1ecade4c6fa221606e6326041b
# bad: [1c90be34ce15659f462ef66976c2f2a19ceb4a81] [CIR] Implement static-local-tls lowering (#194059)
git bisect bad 1c90be34ce15659f462ef66976c2f2a19ceb4a81
# bad: [8062e82db89f12d90e8c331db217904689b87947] [Clang] Emit LLVM flatten attribute instead of per-callsite alwaysinline (#188615)
git bisect bad 8062e82db89f12d90e8c331db217904689b87947
# good: [98fe008141a1fd30eb8cb576c6385a67cf45d111] [offload] Un-XFAIL interop-print.c test for nvidia (#194447)
git bisect good 98fe008141a1fd30eb8cb576c6385a67cf45d111
# first bad commit: [8062e82db89f12d90e8c331db217904689b87947] [Clang] Emit LLVM flatten attribute instead of per-callsite alwaysinline (#188615)
```
Contributor guide
Research direction
Start by reproducing the hang at the Linux kernel build's `LD vmlinux.o` step with `CONFIG_LTO_CLANG_FULL=y` and the supplied `LLVM=1` command. Compare the first bad commit `8062e82db89f` with the good revision and inspect `ld.lld` behavior during that link. Done means the minimal kernel build completes instead of leaving `ld.lld` spinning.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- linux
- Domain
- compilers, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100