From 7c4211fa01bf960ed4dabe36b98920d52a7abdba Mon Sep 17 00:00:00 2001 From: Alan Zhao Date: Wed, 10 Sep 2025 12:38:08 -0700 Subject: [PATCH 1/5] [FunctionSpecialization] Fix profile count preserving logic The previous fix in #157768 had a bug; instead of subtracting the original function's call count per call site of a specialization, we were subtracting the running total of the specialization's calls. Tracking issue: #147390 --- .../Transforms/IPO/FunctionSpecialization.cpp | 6 ++--- .../FunctionSpecialization/profile-counts.ll | 23 +++++++++++-------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp index 30459caee1609..6af23e67f5762 100644 --- a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp +++ b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp @@ -802,8 +802,8 @@ bool FunctionSpecializer::run() { if (std::optional MaybeOriginalCount = S.F->getEntryCount()) { uint64_t OriginalCount = MaybeOriginalCount->getCount(); - if (OriginalCount >= CallCount) { - S.F->setEntryCount(OriginalCount - CallCount); + if (OriginalCount >= *Count) { + S.F->setEntryCount(OriginalCount - *Count); } else { // This should generally not happen as that would mean there are // more computed calls to the function than what was recorded. @@ -1067,7 +1067,7 @@ Function *FunctionSpecializer::createSpecialization(Function *F, // clone must. Clone->setLinkage(GlobalValue::InternalLinkage); - if (F->getEntryCount() && !ProfcheckDisableMetadataFixes) + if (F->getEntryCount()) Clone->setEntryCount(0); // Initialize the lattice state of the arguments of the function clone, diff --git a/llvm/test/Transforms/FunctionSpecialization/profile-counts.ll b/llvm/test/Transforms/FunctionSpecialization/profile-counts.ll index d5b2e35feb118..28428927bc26c 100644 --- a/llvm/test/Transforms/FunctionSpecialization/profile-counts.ll +++ b/llvm/test/Transforms/FunctionSpecialization/profile-counts.ll @@ -13,23 +13,28 @@ entry: ; CHECK: if.then: ; CHECK: call i32 @foo.specialized.1(i32 %x, ptr @A) +; CHECK: call i32 @foo.specialized.2(i32 %y, ptr @B) if.then: %call = call i32 @foo(i32 %x, ptr @A) + %call1 = call i32 @foo(i32 %y, ptr @B) + %call2 = call i32 @foo(i32 %y, ptr @B) + %add = add i32 %call, %call1 + %add1 = add i32 %add, %call2 br label %return ; CHECK: if.else: ; CHECK: call i32 @foo.specialized.2(i32 %y, ptr @B) if.else: - %call1 = call i32 @foo(i32 %y, ptr @B) + %call3 = call i32 @foo(i32 %y, ptr @B) br label %return ; CHECK: return: -; CHECK: %call2 = call i32 @foo(i32 %x, ptr %z) +; CHECK: %call3 = call i32 @foo(i32 %x, ptr %z) return: - %retval.0 = phi i32 [ %call, %if.then ], [ %call1, %if.else ] - %call2 = call i32 @foo(i32 %x, ptr %z); - %add = add i32 %retval.0, %call2 - ret i32 %add + %retval.0 = phi i32 [ %add1, %if.then ], [ %call3, %if.else ] + %call4 = call i32 @foo(i32 %x, ptr %z); + %add2 = add i32 %retval.0, %call4 + ret i32 %add2 } ; CHECK: define internal i32 @foo(i32 %x, ptr %b) !prof ![[FOO_UNSPEC_PROF:[0-9]]] @@ -44,9 +49,9 @@ entry: ; CHECK: ![[BAR_PROF]] = !{!"function_entry_count", i64 1000} ; CHECK: ![[BRANCH_PROF]] = !{!"branch_weights", i32 1, i32 3} -; CHECK: ![[FOO_UNSPEC_PROF]] = !{!"function_entry_count", i64 234} +; CHECK: ![[FOO_UNSPEC_PROF]] = !{!"function_entry_count", i64 500} ; CHECK: ![[FOO_SPEC_1_PROF]] = !{!"function_entry_count", i64 250} -; CHECK: ![[FOO_SPEC_2_PROF]] = !{!"function_entry_count", i64 750} +; CHECK: ![[FOO_SPEC_2_PROF]] = !{!"function_entry_count", i64 1250} !0 = !{!"function_entry_count", i64 1000} !1 = !{!"branch_weights", i32 1, i32 3} -!2 = !{!"function_entry_count", i64 1234} +!2 = !{!"function_entry_count", i64 2000} From 146ff7f2d1416f7164803acdb394e2dd3f810b7b Mon Sep 17 00:00:00 2001 From: Alan Zhao Date: Wed, 10 Sep 2025 12:42:12 -0700 Subject: [PATCH 2/5] undo accidental reverted change --- llvm/lib/Transforms/IPO/FunctionSpecialization.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp index 6af23e67f5762..20d399315fac5 100644 --- a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp +++ b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp @@ -1067,7 +1067,7 @@ Function *FunctionSpecializer::createSpecialization(Function *F, // clone must. Clone->setLinkage(GlobalValue::InternalLinkage); - if (F->getEntryCount()) + if (F->getEntryCount() && !ProfcheckDisableMetadataFixes) Clone->setEntryCount(0); // Initialize the lattice state of the arguments of the function clone, From 16fd512c893655409cec033a2e3cf0a861c49fe7 Mon Sep 17 00:00:00 2001 From: Alan Zhao Date: Wed, 10 Sep 2025 12:43:50 -0700 Subject: [PATCH 3/5] make the test expectations more consistent --- llvm/test/Transforms/FunctionSpecialization/profile-counts.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/Transforms/FunctionSpecialization/profile-counts.ll b/llvm/test/Transforms/FunctionSpecialization/profile-counts.ll index 28428927bc26c..381da5581558a 100644 --- a/llvm/test/Transforms/FunctionSpecialization/profile-counts.ll +++ b/llvm/test/Transforms/FunctionSpecialization/profile-counts.ll @@ -29,7 +29,7 @@ if.else: br label %return ; CHECK: return: -; CHECK: %call3 = call i32 @foo(i32 %x, ptr %z) +; CHECK: call i32 @foo(i32 %x, ptr %z) return: %retval.0 = phi i32 [ %add1, %if.then ], [ %call3, %if.else ] %call4 = call i32 @foo(i32 %x, ptr %z); From 5511d80738cf3f185e6ce3d166aec09b6f960aa3 Mon Sep 17 00:00:00 2001 From: Alan Zhao Date: Wed, 10 Sep 2025 22:36:38 -0700 Subject: [PATCH 4/5] check second call to foo.specialized.2 --- llvm/test/Transforms/FunctionSpecialization/profile-counts.ll | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/test/Transforms/FunctionSpecialization/profile-counts.ll b/llvm/test/Transforms/FunctionSpecialization/profile-counts.ll index 381da5581558a..bdf7690a71b69 100644 --- a/llvm/test/Transforms/FunctionSpecialization/profile-counts.ll +++ b/llvm/test/Transforms/FunctionSpecialization/profile-counts.ll @@ -14,6 +14,7 @@ entry: ; CHECK: if.then: ; CHECK: call i32 @foo.specialized.1(i32 %x, ptr @A) ; CHECK: call i32 @foo.specialized.2(i32 %y, ptr @B) +; CHECK: call i32 @foo.specialized.2(i32 %y, ptr @B) if.then: %call = call i32 @foo(i32 %x, ptr @A) %call1 = call i32 @foo(i32 %y, ptr @B) From 1b0914aea859205277e1c3aa914de355d687f843 Mon Sep 17 00:00:00 2001 From: Alan Zhao Date: Wed, 10 Sep 2025 22:43:03 -0700 Subject: [PATCH 5/5] remove FunctionSpecialization from profcheck-xfail.txt --- llvm/utils/profcheck-xfail.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/utils/profcheck-xfail.txt b/llvm/utils/profcheck-xfail.txt index 0ef391a6d2ed4..2dc739a34493e 100644 --- a/llvm/utils/profcheck-xfail.txt +++ b/llvm/utils/profcheck-xfail.txt @@ -754,7 +754,6 @@ Transforms/FixIrreducible/basic.ll Transforms/FixIrreducible/bug45623.ll Transforms/FixIrreducible/nested.ll Transforms/FixIrreducible/switch.ll -Transforms/FunctionSpecialization/function-specialization3.ll Transforms/GCOVProfiling/atomic-counter.ll Transforms/GCOVProfiling/exit-block.ll Transforms/GCOVProfiling/function-numbering.ll