llvm / llvm/llvm-project

ld.lld hangs when building Linux kernel with full LTO after recent flatten change

Open
#195,236 4 comments 0 reactions 0 assignees View on GitHub
lld
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.