[llvm] f675483 - [profcheck] Annotate `select` instructions (#152171)

via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 5 17:48:54 PDT 2025


Author: Mircea Trofin
Date: 2025-08-06T02:48:50+02:00
New Revision: f67548390582292253e1321a55cdf2c37abe08a7

URL: https://github.com/llvm/llvm-project/commit/f67548390582292253e1321a55cdf2c37abe08a7
DIFF: https://github.com/llvm/llvm-project/commit/f67548390582292253e1321a55cdf2c37abe08a7.diff

LOG: [profcheck] Annotate `select` instructions (#152171)

For `select`, we don't have the equivalent of the branch probability analysis to offer defaults, so we make up our own and allow their overriding with flags.

Issue #147390

Added: 
    llvm/test/Transforms/PGOProfile/profcheck-select.ll

Modified: 
    llvm/lib/Transforms/Utils/ProfileVerify.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/ProfileVerify.cpp b/llvm/lib/Transforms/Utils/ProfileVerify.cpp
index d67192f9d44ee..0ffea3f53fef6 100644
--- a/llvm/lib/Transforms/Utils/ProfileVerify.cpp
+++ b/llvm/lib/Transforms/Utils/ProfileVerify.cpp
@@ -26,6 +26,18 @@ using namespace llvm;
 static cl::opt<int64_t>
     DefaultFunctionEntryCount("profcheck-default-function-entry-count",
                               cl::init(1000));
+static cl::opt<bool>
+    AnnotateSelect("profcheck-annotate-select", cl::init(true),
+                   cl::desc("Also inject (if missing) and verify MD_prof for "
+                            "`select` instructions"));
+static cl::opt<uint32_t> SelectTrueWeight(
+    "profcheck-default-select-true-weight", cl::init(2U),
+    cl::desc("When annotating `select` instructions, this value will be used "
+             "for the first ('true') case."));
+static cl::opt<uint32_t> SelectFalseWeight(
+    "profcheck-default-select-false-weight", cl::init(3U),
+    cl::desc("When annotating `select` instructions, this value will be used "
+             "for the second ('false') case."));
 namespace {
 class ProfileInjector {
   Function &F;
@@ -82,6 +94,13 @@ bool ProfileInjector::inject() {
     return false;
   bool Changed = false;
   for (auto &BB : F) {
+    if (AnnotateSelect) {
+      for (auto &I : BB) {
+        if (isa<SelectInst>(I) && !I.getMetadata(LLVMContext::MD_prof))
+          setBranchWeights(I, {SelectTrueWeight, SelectFalseWeight},
+                           /*IsExpected=*/false);
+      }
+    }
     auto *Term = getTerminatorBenefitingFromMDProf(BB);
     if (!Term || Term->getMetadata(LLVMContext::MD_prof))
       continue;
@@ -144,12 +163,18 @@ PreservedAnalyses ProfileVerifierPass::run(Function &F,
   }
   if (EntryCount->getCount() == 0)
     return PreservedAnalyses::all();
-  for (const auto &BB : F)
+  for (const auto &BB : F) {
+    if (AnnotateSelect) {
+      for (const auto &I : BB)
+        if (isa<SelectInst>(I) && !I.getMetadata(LLVMContext::MD_prof))
+          F.getContext().emitError(
+              "Profile verification failed: select annotation missing");
+    }
     if (const auto *Term =
             ProfileInjector::getTerminatorBenefitingFromMDProf(BB))
       if (!Term->getMetadata(LLVMContext::MD_prof))
         F.getContext().emitError(
             "Profile verification failed: branch annotation missing");
-
+  }
   return PreservedAnalyses::all();
 }

diff  --git a/llvm/test/Transforms/PGOProfile/profcheck-select.ll b/llvm/test/Transforms/PGOProfile/profcheck-select.ll
new file mode 100644
index 0000000000000..b5dc97d2d5a6d
--- /dev/null
+++ b/llvm/test/Transforms/PGOProfile/profcheck-select.ll
@@ -0,0 +1,63 @@
+; RUN: split-file %s %t
+
+; RUN: opt -passes=prof-inject %t/inject.ll -S -o - | FileCheck %t/inject.ll
+
+; RUN: opt -passes=prof-inject %t/inject-some.ll \
+; RUN:   -profcheck-default-select-true-weight=1 -profcheck-default-select-false-weight=6 \
+; RUN:   -S -o - | FileCheck %t/inject-some.ll
+
+; RUN: opt -passes=prof-verify %t/verify.ll 2>&1 | FileCheck %t/verify.ll
+
+; RUN: not opt -passes=prof-verify %t/verify-missing.ll 2>&1 | FileCheck %t/verify-missing.ll
+
+; verify we can disable it. It's sufficient to see opt not failing. 
+; RUN: opt -passes=prof-verify -profcheck-annotate-select=0 %t/verify-missing.ll
+
+;--- inject.ll
+declare void @foo(i32 %a);
+define void @bar(i1 %c) {
+  %v = select i1 %c, i32 1, i32 2
+  call void @foo(i32 %v)
+  ret void
+}
+; CHECK-LABEL: @bar
+; CHECK: %v = select i1 %c, i32 1, i32 2, !prof !1
+; CHECK: !0 = !{!"function_entry_count", i64 1000}
+; CHECK: !1 = !{!"branch_weights", i32 2, i32 3}
+
+;--- inject-some.ll
+declare void @foo(i32 %a);
+define void @bar(i1 %c) {
+  %e = select i1 %c, i32 1, i32 2, !prof !0
+  %c2 = icmp eq i32 %e, 2
+  %v = select i1 %c2, i32 5, i32 10
+  call void @foo(i32 %v)
+  ret void
+}
+!0 = !{!"branch_weights", i32 2, i32 3}
+; CHECK-LABEL: @bar
+; CHECK: %v = select i1 %c2, i32 5, i32 10, !prof !2
+; CHECK: !0 = !{!"function_entry_count", i64 1000}
+; CHECK: !1 = !{!"branch_weights", i32 2, i32 3}
+; CHECK: !2 = !{!"branch_weights", i32 1, i32 6}
+
+;--- verify.ll
+declare void @foo(i32 %a);
+define void @bar(i1 %c) !prof !0 {
+  %v = select i1 %c, i32 1, i32 2, !prof !1
+  call void @foo(i32 %v)
+  ret void
+}
+!0 = !{!"function_entry_count", i64 1000}
+!1 = !{!"branch_weights", i32 1, i32 7}
+; CHECK-NOT: Profile verification failed: select annotation missing
+
+;--- verify-missing.ll
+declare void @foo(i32 %a);
+define void @bar(i1 %c) !prof !0 {
+  %v = select i1 %c, i32 1, i32 2
+  call void @foo(i32 %v)
+  ret void
+}
+!0 = !{!"function_entry_count", i64 1000}
+; CHECK: Profile verification failed: select annotation missing
\ No newline at end of file


        


More information about the llvm-commits mailing list