On 3/6/26 12:57 PM, Josh Poimboeuf wrote:
On Fri, Mar 06, 2026 at 12:55:02PM -0800, Josh Poimboeuf wrote:
On Fri, Mar 06, 2026 at 11:40:21AM -0800, Yonghong Song wrote:
Thanks! Would there be any downsides to enabling this feature
unconditionally in the kernel when the compiler supports it?
The only downside is for the following case:
C file: static function foo()
Asm file: global function foo()
The thin-lto will collect all C files and with the above llvm patch,
the static function foo() may be promoted to global function foo()
if there is no other pre-existing global function foo() in all C files.
In such cases, there will be a conflict since
there are two global function foo() (one from C file, another from Asm file).
In such cases, the build will fail.
How do you think we could hit such issues in linux kernel?
Maybe should have default no for the new config?
I think the chance should be very low. The following is a grab for x86
for global symbols in asm code:
[~/work/others/linux/arch/x86 (master)]$ egrep -r globl
There are actually quite a bit more than that, see SYM_CODE_START:
$ git grep 'SYM_CODE_START(' |wc -l
169
But still, I agree the chance of a conflict would be very low. And
global assembly functions tend to be rather uniquely named.
Maybe we could collect all global symbols in asm codes before lld,
and then we add an option in lld to feed those global symbols (with a file?),
then we can be sure there won't be any conflict?
That wouldn't be worth the effort in my opinion.
I think we should just unconditionally enable
-always-rename-promoted-locals=false when it's available. While that
will implicitly enforce that global asm functions be uniquely named
across the tree, I don't see that as a problem. In the rare case of a
conflict, we can just rename the function.
So you mean we do not need a new config. Should just check clang and
clang versionn like below?
diff --git a/Makefile b/Makefile
index e944c6e71e81..9bd3990024c5 100644
--- a/Makefile
+++ b/Makefile
@@ -1034,6 +1034,11 @@ endif
ifdef CONFIG_LTO_CLANG
ifdef CONFIG_LTO_CLANG_THIN
CC_FLAGS_LTO := -flto=thin -fsplit-lto-unit
+ifdef CONFIG_CC_IS_CLANG
+ifeq ($(shell test $(CONFIG_CLANG_VERSION) -ge 230000; echo $$?),0)
+KBUILD_LDFLAGS += --lto-whole-program-visibility -mllvm
-always-rename-promoted-locals=false
+endif
+endif
else
CC_FLAGS_LTO := -flto
endif
I think this should work. In rare case, renaming the function should
solve the problem.
BTW, reading this again I realize that this would affect not only global
asm *functions*, but also global asm *data*. But asm global data is
quite rare and also tends to be uniquely named, so my conclusion is the
same.
With thin-lto, the cross-file data inlining is a side effect of
cross-file function inlining. So the number of cross-file data inlining
is small. Compared to 1212 number of functions with suffix .llvm.<hash>,
the number of data with suffix only 9:
ffffffff84e8ad09 d __func__.net_ratelimit.llvm.12310750674033017485
ffffffff84f1d569 d .str.llvm.11541892489833206993
ffffffff87f42d40 b __cfs_bandwidth_used.llvm.9245315756205243639
ffffffff87f457c0 b __sched_clock_stable.llvm.13183765431478218167
ffffffff881968d0 b lock_chains_in_use.llvm.17116087415131265585
ffffffff88bba180 b timekeeper_data.llvm.4127123038948722377
ffffffff88bd0eb0 b slab_debugfs_root.llvm.537776758349482510
ffffffff88c0b300 b __acpi_os_prepare_sleep.llvm.3969442148434754585
ffffffff88c63b00 b handshake_rhashtbl.llvm.12810142853876704317
With newly added KBUILD_LDFLAGS flags, none of them have suffixes.
Again, the conflict for data variable should be rare too.
I will repost the patch with Makefile change once llvm23 release
is cut.
Thanks!