[llvm] [JumpTableToSwitch] Fix wrong function used for GUID computation (PR #192877)

Alexander Shaposhnikov via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 19 15:36:08 PDT 2026


https://github.com/alexander-shaposhnikov updated https://github.com/llvm/llvm-project/pull/192877

>From 7d11f9e21f73042bfb6972fedf7ad7d1a5e9cf5a Mon Sep 17 00:00:00 2001
From: Alexander Shaposhnikov <alexander.v.shaposhnikov at gmail.com>
Date: Sun, 19 Apr 2026 15:11:22 -0700
Subject: [PATCH 1/3] [JumpTableToSwitch] Fix wrong function used for GUID
 computation in profile data lookup

---
 .../Transforms/Scalar/JumpTableToSwitch.cpp   |  2 +-
 .../profile-no-guid-metadata.ll               | 41 +++++++++++++++++++
 2 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/Transforms/JumpTableToSwitch/profile-no-guid-metadata.ll

diff --git a/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp b/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp
index a3e3b9a207ca1..4ff9756705320 100644
--- a/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp
@@ -215,7 +215,7 @@ PreservedAnalyses JumpTableToSwitchPass::run(Function &F,
     if (Fct.getMetadata(AssignGUIDPass::GUIDMetadataName))
       return AssignGUIDPass::getGUID(Fct);
 
-    return Function::getGUIDAssumingExternalLinkage(getIRPGOFuncName(F, InLTO));
+    return Function::getGUIDAssumingExternalLinkage(getIRPGOFuncName(Fct, InLTO));
   };
 
   for (BasicBlock &BB : make_early_inc_range(F)) {
diff --git a/llvm/test/Transforms/JumpTableToSwitch/profile-no-guid-metadata.ll b/llvm/test/Transforms/JumpTableToSwitch/profile-no-guid-metadata.ll
new file mode 100644
index 0000000000000..32c416cd9355b
--- /dev/null
+++ b/llvm/test/Transforms/JumpTableToSwitch/profile-no-guid-metadata.ll
@@ -0,0 +1,41 @@
+; RUN: opt < %s -passes=jump-table-to-switch -S | FileCheck %s
+
+;; Test that when target functions lack !guid metadata, the pass correctly
+;; computes GUIDs from the target function names (not the caller's name)
+;; for matching against value profile data. This is a regression test for
+;; a bug where the caller function was used instead of the callee when
+;; computing PGO function names for GUID lookup.
+
+ at jt = constant [2 x ptr] [ptr @jt_target_0, ptr @jt_target_1]
+
+;; Note: these functions intentionally do NOT have !guid metadata,
+;; forcing the pass to compute GUIDs via getIRPGOFuncName.
+define i32 @jt_target_0() {
+  ret i32 10
+}
+
+define i32 @jt_target_1() {
+  ret i32 20
+}
+
+define i32 @caller(i32 %idx) {
+; CHECK-LABEL: define i32 @caller(
+; CHECK:         switch i32 [[IDX:%.*]], label %{{.*}} [
+; CHECK-NEXT:      i32 0, label %[[CALL0:.*]]
+; CHECK-NEXT:      i32 1, label %[[CALL1:.*]]
+; CHECK-NEXT:    ], !prof [[PROF:![0-9]+]]
+; CHECK:       [[CALL0]]:
+; CHECK-NEXT:    {{.*}} = call i32 @jt_target_0()
+; CHECK:       [[CALL1]]:
+; CHECK-NEXT:    {{.*}} = call i32 @jt_target_1()
+  %gep = getelementptr inbounds [2 x ptr], ptr @jt, i32 0, i32 %idx
+  %fptr = load ptr, ptr %gep
+  %r = call i32 %fptr(), !prof !0
+  ret i32 %r
+}
+
+;; VP metadata: GUID 11912887233601027218 = MD5("jt_target_0"), count 100
+;;              GUID 18156790114353049777 = MD5("jt_target_1"), count 50
+!0 = !{!"VP", i32 0, i64 150, i64 11912887233601027218, i64 100, i64 18156790114353049777, i64 50}
+
+; CHECK: [[PROF]] = !{!"branch_weights", i32 0, i32 100, i32 50}

>From 6884ff85441c4cae4d545abebe5e5be8d61c4375 Mon Sep 17 00:00:00 2001
From: Alexander Shaposhnikov <alexander.v.shaposhnikov at gmail.com>
Date: Sun, 19 Apr 2026 15:16:28 -0700
Subject: [PATCH 2/3] Apply clang-format

---
 llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp b/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp
index 4ff9756705320..a236c82827358 100644
--- a/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp
@@ -215,7 +215,8 @@ PreservedAnalyses JumpTableToSwitchPass::run(Function &F,
     if (Fct.getMetadata(AssignGUIDPass::GUIDMetadataName))
       return AssignGUIDPass::getGUID(Fct);
 
-    return Function::getGUIDAssumingExternalLinkage(getIRPGOFuncName(Fct, InLTO));
+    return Function::getGUIDAssumingExternalLinkage(
+        getIRPGOFuncName(Fct, InLTO));
   };
 
   for (BasicBlock &BB : make_early_inc_range(F)) {

>From 8fba6ac81f8ed7cf701280f16f60601db8f5912c Mon Sep 17 00:00:00 2001
From: Alexander Shaposhnikov <alexander.v.shaposhnikov at gmail.com>
Date: Sun, 19 Apr 2026 15:35:56 -0700
Subject: [PATCH 3/3] Address comments

---
 .../Transforms/Scalar/JumpTableToSwitch.cpp   |  2 +-
 .../profile-no-guid-metadata.ll               | 30 +++++++++++++++----
 2 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp b/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp
index a236c82827358..128d23bee20f9 100644
--- a/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp
@@ -211,7 +211,7 @@ PreservedAnalyses JumpTableToSwitchPass::run(Function &F,
   PostDominatorTree *PDT = AM.getCachedResult<PostDominatorTreeAnalysis>(F);
   DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
   bool Changed = false;
-  auto FuncToGuid = [&](const Function &Fct) {
+  auto FuncToGuid = [InLTO = this->InLTO](const Function &Fct) {
     if (Fct.getMetadata(AssignGUIDPass::GUIDMetadataName))
       return AssignGUIDPass::getGUID(Fct);
 
diff --git a/llvm/test/Transforms/JumpTableToSwitch/profile-no-guid-metadata.ll b/llvm/test/Transforms/JumpTableToSwitch/profile-no-guid-metadata.ll
index 32c416cd9355b..f4e71c637608a 100644
--- a/llvm/test/Transforms/JumpTableToSwitch/profile-no-guid-metadata.ll
+++ b/llvm/test/Transforms/JumpTableToSwitch/profile-no-guid-metadata.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
 ; RUN: opt < %s -passes=jump-table-to-switch -S | FileCheck %s
 
 ;; Test that when target functions lack !guid metadata, the pass correctly
@@ -11,23 +12,40 @@
 ;; Note: these functions intentionally do NOT have !guid metadata,
 ;; forcing the pass to compute GUIDs via getIRPGOFuncName.
 define i32 @jt_target_0() {
+; CHECK-LABEL: define i32 @jt_target_0() {
+; CHECK-NEXT:    ret i32 10
+;
   ret i32 10
 }
 
 define i32 @jt_target_1() {
+; CHECK-LABEL: define i32 @jt_target_1() {
+; CHECK-NEXT:    ret i32 20
+;
   ret i32 20
 }
 
 define i32 @caller(i32 %idx) {
 ; CHECK-LABEL: define i32 @caller(
-; CHECK:         switch i32 [[IDX:%.*]], label %{{.*}} [
+; CHECK-SAME: i32 [[IDX:%.*]]) {
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [2 x ptr], ptr @jt, i32 0, i32 [[IDX]]
+; CHECK-NEXT:    [[FPTR:%.*]] = load ptr, ptr [[GEP]], align 8
+; CHECK-NEXT:    switch i32 [[IDX]], label %[[DEFAULT_SWITCH_CASE_UNREACHABLE:.*]] [
 ; CHECK-NEXT:      i32 0, label %[[CALL0:.*]]
 ; CHECK-NEXT:      i32 1, label %[[CALL1:.*]]
-; CHECK-NEXT:    ], !prof [[PROF:![0-9]+]]
+; CHECK-NEXT:    ], !prof [[PROF0:![0-9]+]]
+; CHECK:       [[DEFAULT_SWITCH_CASE_UNREACHABLE]]:
+; CHECK-NEXT:    unreachable
 ; CHECK:       [[CALL0]]:
-; CHECK-NEXT:    {{.*}} = call i32 @jt_target_0()
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @jt_target_0()
+; CHECK-NEXT:    br [[DOTTAIL:label %.*]]
 ; CHECK:       [[CALL1]]:
-; CHECK-NEXT:    {{.*}} = call i32 @jt_target_1()
+; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @jt_target_1()
+; CHECK-NEXT:    br [[DOTTAIL]]
+; CHECK:       [[_TAIL:.*:]]
+; CHECK-NEXT:    [[TMP3:%.*]] = phi i32 [ [[TMP1]], %[[CALL0]] ], [ [[TMP2]], %[[CALL1]] ]
+; CHECK-NEXT:    ret i32 [[TMP3]]
+;
   %gep = getelementptr inbounds [2 x ptr], ptr @jt, i32 0, i32 %idx
   %fptr = load ptr, ptr %gep
   %r = call i32 %fptr(), !prof !0
@@ -38,4 +56,6 @@ define i32 @caller(i32 %idx) {
 ;;              GUID 18156790114353049777 = MD5("jt_target_1"), count 50
 !0 = !{!"VP", i32 0, i64 150, i64 11912887233601027218, i64 100, i64 18156790114353049777, i64 50}
 
-; CHECK: [[PROF]] = !{!"branch_weights", i32 0, i32 100, i32 50}
+;.
+; CHECK: [[PROF0]] = !{!"branch_weights", i32 0, i32 100, i32 50}
+;.



More information about the llvm-commits mailing list