[llvm] [LowerTypeTests] Mark CFI jump table hot if profile summary is present (PR #222230)

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 10 00:19:27 PDT 2026


https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/222230

>From 5535d8ea5f266d6f1660c4db502b22df42d19153 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Tue, 8 Sep 2026 21:21:36 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
 =?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.7
---
 llvm/lib/Transforms/IPO/LowerTypeTests.cpp    | 13 +++
 .../LowerTypeTests/cfi-jumptable-hot.ll       | 82 +++++++++++++++++++
 2 files changed, 95 insertions(+)
 create mode 100644 llvm/test/Transforms/LowerTypeTests/cfi-jumptable-hot.ll

diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
index 35ec5d795495f..ddc7720506f08 100644
--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -1650,6 +1650,19 @@ void LowerTypeTestsModule::createJumpTable(
                                    ConstantAsMetadata::get(ConstantInt::get(
                                        Int64Ty, JumpTableEntrySize))}));
 
+  // The jump table is an artificial function without profile data. Jump tables
+  // with hot entries are expected to be placed in hot sections. Profile
+  // information is not available at this point, so we cannot analyze entry
+  // counts to make a more deliberate decision. However, large cold jump tables
+  // are unlikely (more entries make it more likely that some are hot), and
+  // small cold jump tables will not make much difference in section overhead.
+  // Therefore, mark the jump table hot whenever profile summary is present.
+  if (M.getProfileSummary(/*IsCS=*/false) ||
+      M.getProfileSummary(/*IsCS=*/true)) {
+    F->addFnAttr(Attribute::Hot);
+    F->setSectionPrefix("hot");
+  }
+
   BasicBlock *BB = BasicBlock::Create(M.getContext(), "entry", F);
   IRBuilder<> IRB(BB);
 
diff --git a/llvm/test/Transforms/LowerTypeTests/cfi-jumptable-hot.ll b/llvm/test/Transforms/LowerTypeTests/cfi-jumptable-hot.ll
new file mode 100644
index 0000000000000..b05b04a2a8562
--- /dev/null
+++ b/llvm/test/Transforms/LowerTypeTests/cfi-jumptable-hot.ll
@@ -0,0 +1,82 @@
+; RUN: rm -rf %t && split-file %s %t
+; RUN: opt -S -mtriple=x86_64-unknown-linux -passes=lowertypetests %t/profile.ll | FileCheck --check-prefix=HOT %s
+; RUN: opt -S -mtriple=x86_64-unknown-linux -passes=lowertypetests %t/csprofile.ll | FileCheck --check-prefix=HOT %s
+; RUN: opt -S -mtriple=x86_64-unknown-linux -passes=lowertypetests %t/noprofile.ll | FileCheck --check-prefix=NOHOT %s
+
+; HOT: define private void @.cfi.jumptable() #[[ATTR:[0-9]+]] prefalign(8) !section_prefix ![[PREFIX:[0-9]+]] !elf_section_properties
+; HOT: attributes #[[ATTR]] = { hot naked nocf_check noinline }
+; HOT: ![[PREFIX]] = !{!"section_prefix", !"hot"}
+
+; NOHOT: define private void @.cfi.jumptable() #[[ATTR:[0-9]+]] prefalign(8) !elf_section_properties
+; NOHOT-NOT: !section_prefix
+; NOHOT: attributes #[[ATTR]] = { naked nocf_check noinline }
+
+;--- profile.ll
+target datalayout = "e-p:64:64"
+
+ at 0 = private unnamed_addr constant [2 x ptr] [ptr @f, ptr @g], align 16
+
+define void @f() !type !0 {
+  ret void
+}
+
+define void @g() !type !0 {
+  ret void
+}
+
+declare i1 @llvm.type.test(ptr %ptr, metadata %bitset)
+
+define i1 @foo(ptr %p) {
+  %x = call i1 @llvm.type.test(ptr %p, metadata !"typeid1")
+  ret i1 %x
+}
+
+!0 = !{i32 0, !"typeid1"}
+!llvm.module.flags = !{!1}
+!1 = !{i32 1, !"ProfileSummary", !{}}
+
+;--- csprofile.ll
+target datalayout = "e-p:64:64"
+
+ at 0 = private unnamed_addr constant [2 x ptr] [ptr @f, ptr @g], align 16
+
+define void @f() !type !0 {
+  ret void
+}
+
+define void @g() !type !0 {
+  ret void
+}
+
+declare i1 @llvm.type.test(ptr %ptr, metadata %bitset)
+
+define i1 @foo(ptr %p) {
+  %x = call i1 @llvm.type.test(ptr %p, metadata !"typeid1")
+  ret i1 %x
+}
+
+!0 = !{i32 0, !"typeid1"}
+!llvm.module.flags = !{!1}
+!1 = !{i32 1, !"CSProfileSummary", !{}}
+
+;--- noprofile.ll
+target datalayout = "e-p:64:64"
+
+ at 0 = private unnamed_addr constant [2 x ptr] [ptr @f, ptr @g], align 16
+
+define void @f() !type !0 {
+  ret void
+}
+
+define void @g() !type !0 {
+  ret void
+}
+
+declare i1 @llvm.type.test(ptr %ptr, metadata %bitset)
+
+define i1 @foo(ptr %p) {
+  %x = call i1 @llvm.type.test(ptr %p, metadata !"typeid1")
+  ret i1 %x
+}
+
+!0 = !{i32 0, !"typeid1"}



More information about the llvm-commits mailing list