[llvm] [ThinLTO] Reduce the number of renaming due to promotions in distribu… (PR #188074)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 23 09:58:38 PDT 2026
https://github.com/yonghong-song created https://github.com/llvm/llvm-project/pull/188074
…ted mode
For thin-lto, the pull request [1] reduced the number of renaming due to promotions in process mode. This has been used in linux kernel ([2]) as it helps kernel live patching a lot.
Recently, I found Rong Xu has added thin-lto distributed mode support in linux kenrel ([3]) and it is likely to be merged in kernel as well. So it would be a good idea for llvm to support reducing the number of renaming in distributed mode too.
To implement this, in function gatherImportedSummariesForModule(), import functions into summaries if those functions does not need rename. This will ensure that imported functions have the same name as in there original module.
[1] https://github.com/llvm/llvm-project/pull/183793
[2] https://git.kernel.org/pub/scm/linux/kernel/git/kbuild/linux.git/commit/?h=kbuild-for-next&id=dc3b90751d6ffa8865e09a81645a539b9de6d642
[3] https://lore.kernel.org/linux-kbuild/20251028182822.3210436-3-xur@google.com/
>From ea6a914c3a233d4516004d8f70d85ee71d3ec039 Mon Sep 17 00:00:00 2001
From: Yonghong Song <yonghong.song at linux.dev>
Date: Sun, 22 Mar 2026 11:47:16 -0700
Subject: [PATCH] [ThinLTO] Reduce the number of renaming due to promotions in
distributed mode
For thin-lto, the pull request [1] reduced the number of renaming due to
promotions in process mode. This has been used in linux kernel ([2]) as
it helps kernel live patching a lot.
Recently, I found Rong Xu has added thin-lto distributed mode support in
linux kenrel ([3]) and it is likely to be merged in kernel as well.
So it would be a good idea for llvm to support reducing the number of
renaming in distributed mode too.
To implement this, in function gatherImportedSummariesForModule(),
import functions into summaries if those functions does not need rename.
This will ensure that imported functions have the same name as in there
original module.
[1] https://github.com/llvm/llvm-project/pull/183793
[2] https://git.kernel.org/pub/scm/linux/kernel/git/kbuild/linux.git/commit/?h=kbuild-for-next&id=dc3b90751d6ffa8865e09a81645a539b9de6d642
[3] https://lore.kernel.org/linux-kbuild/20251028182822.3210436-3-xur@google.com/
---
llvm/lib/Transforms/IPO/FunctionImport.cpp | 17 +++++
.../X86/reduce-promotion-distributed.ll | 56 +++++++++++++++
...e-promotion-same-local-name-distributed.ll | 70 +++++++++++++++++++
3 files changed, 143 insertions(+)
create mode 100644 llvm/test/ThinLTO/X86/reduce-promotion-distributed.ll
create mode 100644 llvm/test/ThinLTO/X86/reduce-promotion-same-local-name-distributed.ll
diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp
index 4d4b32749a045..a79cbf324b29c 100644
--- a/llvm/lib/Transforms/IPO/FunctionImport.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp
@@ -1608,6 +1608,23 @@ void llvm::gatherImportedSummariesForModule(
SummariesForIndex[GUID] = DS->second;
}
+
+ // For each source module we import from, also include summaries for local
+ // functions that have NoRenameOnPromotion set. This is needed for distributed
+ // ThinLTO. Otherwise, the local funciton of the source module will keep its
+ // origin name, e.g., foo() while the function in destination module will have
+ // name foo.llvm.<...>() and this will cause a link failure.
+ for (auto &[ModPath, SummariesForIndex] : ModuleToSummariesForIndex) {
+ if (ModPath == ModulePath)
+ continue;
+ auto It = ModuleToDefinedGVSummaries.find(ModPath);
+ if (It == ModuleToDefinedGVSummaries.end())
+ continue;
+ for (const auto &[GUID, Summary] : It->second) {
+ if (Summary->noRenameOnPromotion())
+ SummariesForIndex.try_emplace(GUID, Summary);
+ }
+ }
}
/// Emit the files \p ModulePath will import from into \p OutputFilename.
diff --git a/llvm/test/ThinLTO/X86/reduce-promotion-distributed.ll b/llvm/test/ThinLTO/X86/reduce-promotion-distributed.ll
new file mode 100644
index 0000000000000..6b1d5c52d9cf2
--- /dev/null
+++ b/llvm/test/ThinLTO/X86/reduce-promotion-distributed.ll
@@ -0,0 +1,56 @@
+; This is to test the support for avoiding always renaming in distributed mode.
+
+; RUN: rm -rf %t
+; RUN: mkdir -p %t
+; RUN: split-file %s %t
+
+; RUN: opt -thinlto-bc %t/a.ll -o %t/a.bc
+; RUN: opt -thinlto-bc %t/b.ll -o %t/b.bc
+;
+; RUN: llvm-lto2 run %t/a.bc %t/b.bc \
+; RUN: -thinlto-distributed-indexes \
+; RUN: --whole-program-visibility-enabled-in-lto=true \
+; RUN: -always-rename-promoted-locals=false \
+; RUN: -save-temps -o %t/lto-out \
+; RUN: -r %t/a.bc,m1,px \
+; RUN: -r %t/b.bc,m2,p \
+; RUN: -r %t/a.bc,m2,x
+
+; RUN: opt -passes=function-import -always-rename-promoted-locals=false -import-all-index -enable-import-metadata -summary-file %t/a.bc.thinlto.bc %t/a.bc -o %t/a.bc.out
+; RUN: opt -passes=function-import -always-rename-promoted-locals=false -import-all-index -summary-file %t/b.bc.thinlto.bc %t/b.bc -o %t/b.bc.out
+; RUN: llvm-dis %t/a.bc.out -o - | FileCheck %s --check-prefix=CHECK-A
+; RUN: llvm-dis %t/b.bc.out -o - | FileCheck %s --check-prefix=CHECK-B
+
+; CHECK-A: define available_externally hidden fastcc range(i32 -2147483647, -2147483648) i32 @foo(
+; CHECK-B: define hidden fastcc range(i32 -2147483647, -2147483648) i32 @foo(
+
+;--- a.ll
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-linux-gnu"
+
+define dso_local i32 @m1(i32 noundef %0) local_unnamed_addr {
+ %2 = tail call i32 @m2(i32 noundef %0)
+ ret i32 %2
+}
+
+declare i32 @m2(i32 noundef) local_unnamed_addr
+
+;--- b.ll
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-linux-gnu"
+
+define dso_local i32 @m2(i32 noundef %0) local_unnamed_addr {
+ %2 = tail call fastcc i32 @foo(i32 noundef %0)
+ %3 = shl nsw i32 %0, 1
+ %4 = tail call fastcc i32 @foo(i32 noundef %3)
+ %5 = add nsw i32 %4, %2
+ ret i32 %5
+}
+
+define internal fastcc range(i32 -2147483647, -2147483648) i32 @foo(i32 noundef %0) unnamed_addr #1 {
+ %2 = add nsw i32 %0, 5
+ %3 = sdiv i32 %2, %0
+ ret i32 %3
+}
+
+attributes #1 = { noinline }
diff --git a/llvm/test/ThinLTO/X86/reduce-promotion-same-local-name-distributed.ll b/llvm/test/ThinLTO/X86/reduce-promotion-same-local-name-distributed.ll
new file mode 100644
index 0000000000000..817c89ae398b7
--- /dev/null
+++ b/llvm/test/ThinLTO/X86/reduce-promotion-same-local-name-distributed.ll
@@ -0,0 +1,70 @@
+; This is to test the support for avoiding always renaming in distributed mode,
+; and ensure that one copy is still renamed despite having different GUIDs.
+
+; RUN: rm -rf %t
+; RUN: mkdir -p %t
+; RUN: split-file %s %t
+
+; RUN: opt -thinlto-bc %t/a.ll -o %t/a.bc
+; RUN: opt -thinlto-bc %t/b.ll -o %t/b.bc
+;
+; RUN: llvm-lto2 run %t/a.bc %t/b.bc \
+; RUN: -thinlto-distributed-indexes \
+; RUN: --whole-program-visibility-enabled-in-lto=true \
+; RUN: -always-rename-promoted-locals=false \
+; RUN: -save-temps -o %t/lto-out \
+; RUN: -r %t/a.bc,m1,px \
+; RUN: -r %t/b.bc,m2,p \
+; RUN: -r %t/a.bc,m2,x
+
+; RUN: opt -passes=function-import -always-rename-promoted-locals=false -import-all-index -enable-import-metadata -summary-file %t/a.bc.thinlto.bc %t/a.bc -o %t/a.bc.out
+; RUN: opt -passes=function-import -always-rename-promoted-locals=false -import-all-index -summary-file %t/b.bc.thinlto.bc %t/b.bc -o %t/b.bc.out
+; RUN: llvm-dis %t/a.bc.out -o - | FileCheck %s --check-prefix=CHECK-A
+; RUN: llvm-dis %t/b.bc.out -o - | FileCheck %s --check-prefix=CHECK-B
+
+; CHECK-A: define hidden fastcc range(i32 -2147483647, -2147483648) i32 @foo.llvm.
+; CHECK-A: define available_externally hidden fastcc range(i32 -2147483647, -2147483648) i32 @foo(
+; CHECK-B: define hidden fastcc range(i32 -2147483647, -2147483648) i32 @foo(
+
+;--- a.ll
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-linux-gnu"
+
+define dso_local i32 @m1(i32 noundef %0) local_unnamed_addr {
+ %2 = shl nsw i32 %0, 1
+ %3 = tail call fastcc i32 @foo(i32 noundef %2)
+ %4 = tail call i32 @m2(i32 noundef %0)
+ %5 = add nsw i32 %4, %3
+ ret i32 %5
+}
+
+define internal fastcc range(i32 -2147483647, -2147483648) i32 @foo(i32 noundef %0) unnamed_addr #1 {
+ %2 = add nsw i32 %0, 5
+ %3 = sdiv i32 %2, %0
+ ret i32 %3
+}
+
+declare i32 @m2(i32 noundef) local_unnamed_addr
+
+attributes #1 = { noinline }
+
+;--- b.ll
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-linux-gnu"
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable
+define dso_local i32 @m2(i32 noundef %0) local_unnamed_addr {
+ %2 = tail call fastcc i32 @foo(i32 noundef %0)
+ %3 = shl nsw i32 %0, 1
+ %4 = tail call fastcc i32 @foo(i32 noundef %3)
+ %5 = add nsw i32 %4, %2
+ ret i32 %5
+}
+
+define internal fastcc range(i32 -2147483647, -2147483648) i32 @foo(i32 noundef %0) unnamed_addr #1 {
+ %2 = add nsw i32 %0, 5
+ %3 = sdiv i32 %2, %0
+ ret i32 %3
+}
+
+attributes #1 = { noinline }
More information about the llvm-commits
mailing list