Skip to content

Conversation

alanzhao1
Copy link
Contributor

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

The previous fix in llvm#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: llvm#147390
@llvmbot
Copy link
Member

llvmbot commented Sep 10, 2025

@llvm/pr-subscribers-function-specialization

@llvm/pr-subscribers-llvm-transforms

Author: Alan Zhao (alanzhao1)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/157939.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/IPO/FunctionSpecialization.cpp (+3-3)
  • (modified) llvm/test/Transforms/FunctionSpecialization/profile-counts.ll (+14-9)
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<llvm::Function::ProfileCount> 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}

@alanzhao1 alanzhao1 enabled auto-merge (squash) September 11, 2025 05:36
Copy link
Member

mtrofin commented Sep 11, 2025

btw, you can remove this test from llvm/utils/profcheck-xfail.txt

@alanzhao1
Copy link
Contributor Author

btw, you can remove this test from llvm/utils/profcheck-xfail.txt

Done

@alanzhao1 alanzhao1 closed this Sep 11, 2025
auto-merge was automatically disabled September 11, 2025 05:43

Pull request was closed

@alanzhao1 alanzhao1 reopened this Sep 11, 2025
@alanzhao1 alanzhao1 enabled auto-merge (squash) September 11, 2025 05:43
@alanzhao1 alanzhao1 merged commit bf6debc into llvm:main Sep 11, 2025
16 of 17 checks passed
@alanzhao1 alanzhao1 deleted the bugfix/func-spec-prof-fix branch September 11, 2025 06:44
@llvm-ci
Copy link
Collaborator

llvm-ci commented Sep 11, 2025

LLVM Buildbot has detected a new failure on builder sanitizer-x86_64-linux running on sanitizer-buildbot2 while building llvm at step 2 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/66/builds/19111

Here is the relevant piece of the build log for the reference
Step 2 (annotate) failure: 'python ../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py' (failure)
...
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:248: warning: COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=ON, but this test suite does not support testing the just-built runtime libraries when the test compiler is configured to use different runtime libraries. Either modify this test suite to support this test configuration, or set COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=OFF to test the runtime libraries included in the compiler instead.
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:259: note: Testing using libraries in "/home/b/sanitizer-x86_64-linux/build/build_default/./lib/../lib/clang/22/lib/i386-unknown-linux-gnu"
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:237: warning: Compiler lib dir != compiler-rt lib dir
Compiler libdir:     "/home/b/sanitizer-x86_64-linux/build/build_default/lib/clang/22/lib/i386-unknown-linux-gnu"
compiler-rt libdir:  "/home/b/sanitizer-x86_64-linux/build/build_default/lib/clang/22/lib/x86_64-unknown-linux-gnu"
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:248: warning: COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=ON, but this test suite does not support testing the just-built runtime libraries when the test compiler is configured to use different runtime libraries. Either modify this test suite to support this test configuration, or set COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=OFF to test the runtime libraries included in the compiler instead.
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:259: note: Testing using libraries in "/home/b/sanitizer-x86_64-linux/build/build_default/./lib/../lib/clang/22/lib/x86_64-unknown-linux-gnu"
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/llvm/utils/lit/lit/main.py:74: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 900 seconds was requested on the command line. Forcing timeout to be 900 seconds.
-- Testing: 10899 tests, 88 workers --
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70
FAIL: ThreadSanitizer-x86_64 :: cxa_guard_acquire.cpp (8209 of 10899)
******************** TEST 'ThreadSanitizer-x86_64 :: cxa_guard_acquire.cpp' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
/home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang  --driver-mode=g++ -fsanitize=thread -Wall  -m64  -msse4.2   -gline-tables-only -I/home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/../ -std=c++11 -I/home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/../ -nostdinc++ -I/home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/tsan/libcxx_tsan_x86_64/include/c++/v1 -O1 /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/cxa_guard_acquire.cpp -o /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/tsan/X86_64Config/Output/cxa_guard_acquire.cpp.tmp &&  /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/tsan/X86_64Config/Output/cxa_guard_acquire.cpp.tmp 2>&1 | FileCheck /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/cxa_guard_acquire.cpp # RUN: at line 1
+ /home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang --driver-mode=g++ -fsanitize=thread -Wall -m64 -msse4.2 -gline-tables-only -I/home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/../ -std=c++11 -I/home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/../ -nostdinc++ -I/home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/tsan/libcxx_tsan_x86_64/include/c++/v1 -O1 /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/cxa_guard_acquire.cpp -o /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/tsan/X86_64Config/Output/cxa_guard_acquire.cpp.tmp
+ /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/tsan/X86_64Config/Output/cxa_guard_acquire.cpp.tmp
+ FileCheck /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/cxa_guard_acquire.cpp
/home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/cxa_guard_acquire.cpp:71:17: error: CHECK-NEXT: is not on the line after the previous match
 // CHECK-NEXT: Enter constructor
                ^
<stdin>:3:1: note: 'next' match was here
Enter constructor
^
<stdin>:1:11: note: previous match ended here
Enter main
          ^
<stdin>:2:1: note: non-matching line after previous match is here
Enter potentially blocking region
^

Input file: <stdin>
Check file: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/cxa_guard_acquire.cpp

-dump-input=help explains the following input dump.

Input was:
<<<<<<
         1: Enter main 
         2: Enter potentially blocking region 
         3: Enter constructor 
next:71     !~~~~~~~~~~~~~~~~  error: match on wrong line
         4: Exit constructor 
         5: Exit potentially blocking region 
         6: Enter constructor 2 
         7: Exit main 
>>>>>>
Step 14 (test compiler-rt default) failure: test compiler-rt default (failure)
...
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:248: warning: COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=ON, but this test suite does not support testing the just-built runtime libraries when the test compiler is configured to use different runtime libraries. Either modify this test suite to support this test configuration, or set COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=OFF to test the runtime libraries included in the compiler instead.
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:259: note: Testing using libraries in "/home/b/sanitizer-x86_64-linux/build/build_default/./lib/../lib/clang/22/lib/i386-unknown-linux-gnu"
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:237: warning: Compiler lib dir != compiler-rt lib dir
Compiler libdir:     "/home/b/sanitizer-x86_64-linux/build/build_default/lib/clang/22/lib/i386-unknown-linux-gnu"
compiler-rt libdir:  "/home/b/sanitizer-x86_64-linux/build/build_default/lib/clang/22/lib/x86_64-unknown-linux-gnu"
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:248: warning: COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=ON, but this test suite does not support testing the just-built runtime libraries when the test compiler is configured to use different runtime libraries. Either modify this test suite to support this test configuration, or set COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=OFF to test the runtime libraries included in the compiler instead.
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:259: note: Testing using libraries in "/home/b/sanitizer-x86_64-linux/build/build_default/./lib/../lib/clang/22/lib/x86_64-unknown-linux-gnu"
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/llvm/utils/lit/lit/main.py:74: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 900 seconds was requested on the command line. Forcing timeout to be 900 seconds.
-- Testing: 10899 tests, 88 workers --
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70
FAIL: ThreadSanitizer-x86_64 :: cxa_guard_acquire.cpp (8209 of 10899)
******************** TEST 'ThreadSanitizer-x86_64 :: cxa_guard_acquire.cpp' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
/home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang  --driver-mode=g++ -fsanitize=thread -Wall  -m64  -msse4.2   -gline-tables-only -I/home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/../ -std=c++11 -I/home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/../ -nostdinc++ -I/home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/tsan/libcxx_tsan_x86_64/include/c++/v1 -O1 /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/cxa_guard_acquire.cpp -o /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/tsan/X86_64Config/Output/cxa_guard_acquire.cpp.tmp &&  /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/tsan/X86_64Config/Output/cxa_guard_acquire.cpp.tmp 2>&1 | FileCheck /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/cxa_guard_acquire.cpp # RUN: at line 1
+ /home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang --driver-mode=g++ -fsanitize=thread -Wall -m64 -msse4.2 -gline-tables-only -I/home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/../ -std=c++11 -I/home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/../ -nostdinc++ -I/home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/lib/tsan/libcxx_tsan_x86_64/include/c++/v1 -O1 /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/cxa_guard_acquire.cpp -o /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/tsan/X86_64Config/Output/cxa_guard_acquire.cpp.tmp
+ /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/tsan/X86_64Config/Output/cxa_guard_acquire.cpp.tmp
+ FileCheck /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/cxa_guard_acquire.cpp
/home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/cxa_guard_acquire.cpp:71:17: error: CHECK-NEXT: is not on the line after the previous match
 // CHECK-NEXT: Enter constructor
                ^
<stdin>:3:1: note: 'next' match was here
Enter constructor
^
<stdin>:1:11: note: previous match ended here
Enter main
          ^
<stdin>:2:1: note: non-matching line after previous match is here
Enter potentially blocking region
^

Input file: <stdin>
Check file: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/tsan/cxa_guard_acquire.cpp

-dump-input=help explains the following input dump.

Input was:
<<<<<<
         1: Enter main 
         2: Enter potentially blocking region 
         3: Enter constructor 
next:71     !~~~~~~~~~~~~~~~~  error: match on wrong line
         4: Exit constructor 
         5: Exit potentially blocking region 
         6: Enter constructor 2 
         7: Exit main 
>>>>>>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants