From 1e5493b1b84473e42bc9992f6684e51eeb335f14 Mon Sep 17 00:00:00 2001 From: Maksim Panchenko Date: Sat, 7 Feb 2026 20:39:24 -0800 Subject: [PATCH] [BOLT] Don't fold hot text mover functions in ICF (#180367) Hot text mover functions are placed in special sections (e.g., .never_hugify) to avoid being placed on hot/huge pages. Folding them with functions from other sections could defeat this purpose. Add a check in ICF's isIdenticalWith() to prevent folding when either function is a hot text mover. --- bolt/lib/Passes/IdenticalCodeFolding.cpp | 7 +++++++ bolt/test/icf-hot-text-mover.c | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 bolt/test/icf-hot-text-mover.c diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp index b63bab75540b..1c99a60bfaad 100644 --- a/bolt/lib/Passes/IdenticalCodeFolding.cpp +++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp @@ -33,6 +33,8 @@ namespace opts { extern cl::OptionCategory BoltOptCategory; +extern bool isHotTextMover(const BinaryFunction &Function); + static cl::opt ICFUseDFS("icf-dfs", cl::desc("use DFS ordering when using -icf option"), cl::ReallyHidden, cl::cat(BoltOptCategory)); @@ -186,6 +188,11 @@ static bool isIdenticalWith(const BinaryFunction &A, const BinaryFunction &B, bool CongruentSymbols) { assert(A.hasCFG() && B.hasCFG() && "both functions should have CFG"); + // Hot text mover functions should not be folded. They need to stay in their + // original section to avoid being placed on hot/huge pages. + if (opts::isHotTextMover(A) || opts::isHotTextMover(B)) + return false; + // Compare the two functions, one basic block at a time. // Currently we require two identical basic blocks to have identical // instruction sequences and the same index in their corresponding diff --git a/bolt/test/icf-hot-text-mover.c b/bolt/test/icf-hot-text-mover.c new file mode 100644 index 000000000000..3ecfe9b2c135 --- /dev/null +++ b/bolt/test/icf-hot-text-mover.c @@ -0,0 +1,24 @@ +// Check that ICF does not fold hot text mover functions. +// Hot text mover functions are placed in special sections (e.g., .never_hugify) +// to avoid being placed on hot/huge pages. + +// clang-format off + +// REQUIRES: system-linux, asserts +// RUN: %clang %cflags -O0 %s -o %t.exe -Wl,-q +// RUN: llvm-bolt %t.exe --icf --hot-text-move-sections=.never_hugify \ +// RUN: -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck %s + +// FuncA is in .text, FuncB is in .never_hugify (a hot text mover section). +// They are identical, but FuncB should NOT be folded because it is a hot text mover. +// CHECK: ICF iteration 1 +// CHECK-NOT: folding FuncB into FuncA +// CHECK-NOT: folding FuncA into FuncB + +__attribute__((noinline)) int FuncA(void) { return 42; } + +__attribute__((section(".never_hugify"), noinline)) int FuncB(void) { + return 42; +} + +int main(void) { return FuncA() + FuncB(); }