Skip to content

Conversation

mtrofin
Copy link
Member

@mtrofin mtrofin commented Sep 18, 2025

Propagate !prof​ from switch​ instructions.

Issue #147390

@mtrofin mtrofin marked this pull request as ready for review September 18, 2025 20:17
Copy link

github-actions bot commented Sep 18, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@llvmbot
Copy link
Member

llvmbot commented Sep 18, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Mircea Trofin (mtrofin)

Changes

Patch is 21.02 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/159645.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/Utils/SimplifyCFG.cpp (+75-11)
  • (modified) llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll (+42-30)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index a1f759dd1df83..276ca89d715f1 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -84,6 +84,7 @@
 #include <cstdint>
 #include <iterator>
 #include <map>
+#include <numeric>
 #include <optional>
 #include <set>
 #include <tuple>
@@ -6318,9 +6319,12 @@ static bool initializeUniqueCases(SwitchInst *SI, PHINode *&PHI,
 // Helper function that checks if it is possible to transform a switch with only
 // two cases (or two cases + default) that produces a result into a select.
 // TODO: Handle switches with more than 2 cases that map to the same result.
+// The branch weights correspond to the provided Condition (i.e. if Condition is
+// modified from the original SwitchInst, the caller must adjust the weights)
 static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
                                  Constant *DefaultResult, Value *Condition,
-                                 IRBuilder<> &Builder, const DataLayout &DL) {
+                                 IRBuilder<> &Builder, const DataLayout &DL,
+                                 ArrayRef<uint32_t> BranchWeights) {
   // If we are selecting between only two cases transform into a simple
   // select or a two-way select if default is possible.
   // Example:
@@ -6329,6 +6333,10 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
   //   case 20: return 2;   ---->  %2 = icmp eq i32 %a, 20
   //   default: return 4;          %3 = select i1 %2, i32 2, i32 %1
   // }
+
+  const bool HasBranchWeights =
+      !BranchWeights.empty() && !ProfcheckDisableMetadataFixes;
+
   if (ResultVector.size() == 2 && ResultVector[0].second.size() == 1 &&
       ResultVector[1].second.size() == 1) {
     ConstantInt *FirstCase = ResultVector[0].second[0];
@@ -6337,13 +6345,37 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
     if (DefaultResult) {
       Value *ValueCompare =
           Builder.CreateICmpEQ(Condition, SecondCase, "switch.selectcmp");
-      SelectValue = Builder.CreateSelect(ValueCompare, ResultVector[1].first,
-                                         DefaultResult, "switch.select");
+      SelectInst *SelectValueInst = cast<SelectInst>(Builder.CreateSelect(
+          ValueCompare, ResultVector[1].first, DefaultResult, "switch.select"));
+      SelectValue = SelectValueInst;
+      if (HasBranchWeights) {
+        // We start with 3 probabilities, where the numerator is the
+        // corresponding BranchWeights[i], and the denominator is the sum over
+        // BranchWeights. We want the probability and negative probability of
+        // Condition == SecondCase.
+        assert(BranchWeights.size() == 3);
+        setBranchWeights(SelectValueInst, BranchWeights[2],
+                         BranchWeights[0] + BranchWeights[1],
+                         /*IsExpected=*/false);
+        }
     }
     Value *ValueCompare =
         Builder.CreateICmpEQ(Condition, FirstCase, "switch.selectcmp");
-    return Builder.CreateSelect(ValueCompare, ResultVector[0].first,
-                                SelectValue, "switch.select");
+    SelectInst *Ret = cast<SelectInst>(Builder.CreateSelect(
+        ValueCompare, ResultVector[0].first, SelectValue, "switch.select"));
+    if (HasBranchWeights) {
+      // We may have had a DefaultResult. Base the position of the first and
+      // second's branch weights accordingly. Also the proability that Condition
+      // != FirstCase needs to take that into account.
+      assert(BranchWeights.size() >= 2);
+      size_t FirstCasePos = (Condition != nullptr);
+      size_t SecondCasePos = FirstCasePos + 1;
+      uint32_t DefaultCase = (Condition != nullptr) ? BranchWeights[0] : 0;
+      setBranchWeights(Ret, BranchWeights[FirstCasePos],
+                       DefaultCase + BranchWeights[SecondCasePos],
+                       /*IsExpected=*/false);
+    }
+    return Ret;
   }
 
   // Handle the degenerate case where two cases have the same result value.
@@ -6379,8 +6411,16 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
           Value *And = Builder.CreateAnd(Condition, AndMask);
           Value *Cmp = Builder.CreateICmpEQ(
               And, Constant::getIntegerValue(And->getType(), AndMask));
-          return Builder.CreateSelect(Cmp, ResultVector[0].first,
-                                      DefaultResult);
+          SelectInst *Ret = cast<SelectInst>(Builder.CreateSelect(Cmp, ResultVector[0].first,
+                                      DefaultResult));
+          if (HasBranchWeights) {
+            // We know there's a Default case. We base the resulting branch
+            // weights off its probability.
+            assert(BranchWeights.size() >= 2);
+            setBranchWeights(Ret, accumulate(drop_begin(BranchWeights), 0),
+                             BranchWeights[0], /*IsExpected=*/false);
+          }
+          return Ret;
         }
       }
 
@@ -6397,7 +6437,14 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
         Value *And = Builder.CreateAnd(Condition, ~BitMask, "switch.and");
         Value *Cmp = Builder.CreateICmpEQ(
             And, Constant::getNullValue(And->getType()), "switch.selectcmp");
-        return Builder.CreateSelect(Cmp, ResultVector[0].first, DefaultResult);
+        SelectInst *Ret = cast<SelectInst>(
+            Builder.CreateSelect(Cmp, ResultVector[0].first, DefaultResult));
+        if (HasBranchWeights) {
+          assert(BranchWeights.size() >= 2);
+          setBranchWeights(Ret, accumulate(drop_begin(BranchWeights), 0),
+                           BranchWeights[0], /*IsExpected=*/false);
+        }
+        return Ret;
       }
     }
 
@@ -6408,7 +6455,14 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
       Value *Cmp2 = Builder.CreateICmpEQ(Condition, CaseValues[1],
                                          "switch.selectcmp.case2");
       Value *Cmp = Builder.CreateOr(Cmp1, Cmp2, "switch.selectcmp");
-      return Builder.CreateSelect(Cmp, ResultVector[0].first, DefaultResult);
+      SelectInst *Ret = cast<SelectInst>(
+          Builder.CreateSelect(Cmp, ResultVector[0].first, DefaultResult));
+      if (HasBranchWeights) {
+        assert(BranchWeights.size() >= 2);
+        setBranchWeights(Ret, accumulate(drop_begin(BranchWeights), 0),
+                         BranchWeights[0], /*IsExpected=*/false);
+      }
+      return Ret;
     }
   }
 
@@ -6469,8 +6523,18 @@ static bool trySwitchToSelect(SwitchInst *SI, IRBuilder<> &Builder,
 
   assert(PHI != nullptr && "PHI for value select not found");
   Builder.SetInsertPoint(SI);
-  Value *SelectValue =
-      foldSwitchToSelect(UniqueResults, DefaultResult, Cond, Builder, DL);
+  SmallVector<uint32_t, 4> BranchWeights;
+  if (!ProfcheckDisableMetadataFixes) {
+    [[maybe_unused]] auto HasWeights =
+        extractBranchWeights(getBranchWeightMDNode(*SI), BranchWeights);
+    assert(!HasWeights == (BranchWeights.empty()));
+  }
+  assert(BranchWeights.empty() ||
+         (BranchWeights.size() >=
+          UniqueResults.size() + (DefaultResult != nullptr)));
+
+  Value *SelectValue = foldSwitchToSelect(UniqueResults, DefaultResult, Cond,
+                                          Builder, DL, BranchWeights);
   if (!SelectValue)
     return false;
 
diff --git a/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll b/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
index fe2e897125eb8..e0e00c1154059 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
@@ -1,5 +1,5 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
+; RUN: opt < %s -passes=prof-inject,simplifycfg -profcheck-weights-for-test -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
 
 ; int foo1_with_default(int a) {
 ;   switch(a) {
@@ -15,9 +15,9 @@ define i32 @foo1_with_default(i32 %a) {
 ; CHECK-LABEL: @foo1_with_default(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[A:%.*]], 20
-; CHECK-NEXT:    [[SWITCH_SELECT:%.*]] = select i1 [[SWITCH_SELECTCMP]], i32 2, i32 4
+; CHECK-NEXT:    [[SWITCH_SELECT:%.*]] = select i1 [[SWITCH_SELECTCMP]], i32 2, i32 4, !prof [[PROF1:![0-9]+]]
 ; CHECK-NEXT:    [[SWITCH_SELECTCMP1:%.*]] = icmp eq i32 [[A]], 10
-; CHECK-NEXT:    [[SWITCH_SELECT2:%.*]] = select i1 [[SWITCH_SELECTCMP1]], i32 10, i32 [[SWITCH_SELECT]]
+; CHECK-NEXT:    [[SWITCH_SELECT2:%.*]] = select i1 [[SWITCH_SELECTCMP1]], i32 10, i32 [[SWITCH_SELECT]], !prof [[PROF2:![0-9]+]]
 ; CHECK-NEXT:    ret i32 [[SWITCH_SELECT2]]
 ;
 entry:
@@ -47,7 +47,7 @@ define i32 @same_value(i32 %a) {
 ; CHECK-NEXT:    [[SWITCH_SELECTCMP_CASE1:%.*]] = icmp eq i32 [[A:%.*]], 10
 ; CHECK-NEXT:    [[SWITCH_SELECTCMP_CASE2:%.*]] = icmp eq i32 [[A]], 20
 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = or i1 [[SWITCH_SELECTCMP_CASE1]], [[SWITCH_SELECTCMP_CASE2]]
-; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[SWITCH_SELECTCMP]], i32 10, i32 4
+; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[SWITCH_SELECTCMP]], i32 10, i32 4, !prof [[PROF3:![0-9]+]]
 ; CHECK-NEXT:    ret i32 [[TMP0]]
 ;
 entry:
@@ -71,7 +71,7 @@ define i1 @switch_to_select_same2_case_results_different_default(i8 %0) {
 ; CHECK-LABEL: @switch_to_select_same2_case_results_different_default(
 ; CHECK-NEXT:    [[SWITCH_AND:%.*]] = and i8 [[TMP0:%.*]], -5
 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i8 [[SWITCH_AND]], 0
-; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false, !prof [[PROF3]]
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   switch i8 %0, label %2 [
@@ -92,7 +92,7 @@ define i1 @switch_to_select_same2_case_results_different_default_and_positive_of
 ; CHECK-NEXT:    [[TMP2:%.*]] = sub i8 [[TMP0:%.*]], 43
 ; CHECK-NEXT:    [[SWITCH_AND:%.*]] = and i8 [[TMP2]], -3
 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i8 [[SWITCH_AND]], 0
-; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false
+; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false, !prof [[PROF3]]
 ; CHECK-NEXT:    ret i1 [[TMP3]]
 ;
   switch i8 %0, label %2 [
@@ -114,7 +114,7 @@ define i8 @switch_to_select_same2_case_results_different_default_and_negative_of
 ; CHECK-NEXT:    [[TMP0:%.*]] = sub i32 [[I:%.*]], -5
 ; CHECK-NEXT:    [[SWITCH_AND:%.*]] = and i32 [[TMP0]], -3
 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[SWITCH_AND]], 0
-; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[SWITCH_SELECTCMP]], i8 3, i8 42
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[SWITCH_SELECTCMP]], i8 3, i8 42, !prof [[PROF3]]
 ; CHECK-NEXT:    ret i8 [[TMP1]]
 ;
 entry:
@@ -136,7 +136,7 @@ define i1 @switch_to_select_same4_case_results_different_default(i32 %i) {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[SWITCH_AND:%.*]] = and i32 [[I:%.*]], -7
 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[SWITCH_AND]], 0
-; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false
+; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false, !prof [[PROF4:![0-9]+]]
 ; CHECK-NEXT:    ret i1 [[TMP0]]
 ;
 entry:
@@ -160,7 +160,7 @@ define i1 @switch_to_select_same4_case_results_different_default_alt_bitmask(i32
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[SWITCH_AND:%.*]] = and i32 [[I:%.*]], -11
 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[SWITCH_AND]], 0
-; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false
+; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false, !prof [[PROF4]]
 ; CHECK-NEXT:    ret i1 [[TMP0]]
 ;
 entry:
@@ -185,7 +185,7 @@ define i1 @switch_to_select_same4_case_results_different_default_positive_offset
 ; CHECK-NEXT:    [[TMP0:%.*]] = sub i32 [[I:%.*]], 2
 ; CHECK-NEXT:    [[SWITCH_AND:%.*]] = and i32 [[TMP0]], -11
 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[SWITCH_AND]], 0
-; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false, !prof [[PROF4]]
 ; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
 entry:
@@ -212,7 +212,7 @@ define i1 @switch_to_select_invalid_mask(i32 %i) {
 ; CHECK-NEXT:      i32 4, label [[LOR_END]]
 ; CHECK-NEXT:      i32 10, label [[LOR_END]]
 ; CHECK-NEXT:      i32 12, label [[LOR_END]]
-; CHECK-NEXT:    ]
+; CHECK-NEXT:    ], !prof [[PROF5:![0-9]+]]
 ; CHECK:       lor.rhs:
 ; CHECK-NEXT:    br label [[LOR_END]]
 ; CHECK:       lor.end:
@@ -242,7 +242,7 @@ define i1 @switch_to_select_nonpow2_cases(i32 %i) {
 ; CHECK-NEXT:      i32 0, label [[LOR_END:%.*]]
 ; CHECK-NEXT:      i32 2, label [[LOR_END]]
 ; CHECK-NEXT:      i32 4, label [[LOR_END]]
-; CHECK-NEXT:    ]
+; CHECK-NEXT:    ], !prof [[PROF6:![0-9]+]]
 ; CHECK:       lor.rhs:
 ; CHECK-NEXT:    br label [[LOR_END]]
 ; CHECK:       lor.end:
@@ -273,7 +273,7 @@ define i8 @switch_to_select_two_case_results_no_default(i32 %i) {
 ; CHECK-NEXT:      i32 2, label [[END]]
 ; CHECK-NEXT:      i32 4, label [[CASE3:%.*]]
 ; CHECK-NEXT:      i32 6, label [[CASE3]]
-; CHECK-NEXT:    ]
+; CHECK-NEXT:    ], !prof [[PROF5]]
 ; CHECK:       case3:
 ; CHECK-NEXT:    br label [[END]]
 ; CHECK:       default:
@@ -315,7 +315,7 @@ define i1 @no_range(i8 %f) {
 ; CHECK-NEXT:  bb3:
 ; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[F:%.*]], 60
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 60
-; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false, !prof [[PROF7:![0-9]+]]
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   switch i8 %f, label %bb1 [
@@ -364,7 +364,7 @@ define i1 @negative_no_range(i8 %f) {
 ; CHECK-NEXT:      i8 -3, label [[BB2]]
 ; CHECK-NEXT:      i8 -2, label [[BB2]]
 ; CHECK-NEXT:      i8 -1, label [[BB2]]
-; CHECK-NEXT:    ]
+; CHECK-NEXT:    ], !prof [[PROF8:![0-9]+]]
 ; CHECK:       bb2:
 ; CHECK-NEXT:    br label [[BB3]]
 ; CHECK:       bb3:
@@ -405,7 +405,7 @@ define i1 @range0to4odd(i8 range(i8 0, 4) %f) {
 ; CHECK-NEXT:  bb3:
 ; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[F:%.*]], 1
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 1
-; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false, !prof [[PROF3]]
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   switch i8 %f, label %bb1 [
@@ -426,7 +426,7 @@ define i1 @range1to4odd(i8 range(i8 1, 4) %f) {
 ; CHECK-NEXT:  bb3:
 ; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[F:%.*]], 1
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 1
-; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false, !prof [[PROF3]]
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   switch i8 %f, label %bb1 [
@@ -447,7 +447,7 @@ define i1 @range0to8odd(i8 range(i8 0, 8) %f) {
 ; CHECK-NEXT:  bb3:
 ; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[F:%.*]], 1
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 1
-; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false, !prof [[PROF4]]
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   switch i8 %f, label %bb1 [
@@ -470,7 +470,7 @@ define i1 @range0to8most_significant_bit(i8 range(i8 0, 8) %f) {
 ; CHECK-NEXT:  bb3:
 ; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[F:%.*]], 4
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 4
-; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false, !prof [[PROF4]]
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   switch i8 %f, label %bb1 [
@@ -493,7 +493,7 @@ define i1 @range0to15_middle_two_bits(i8 range(i8 0, 16) %f) {
 ; CHECK-NEXT:  bb3:
 ; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[F:%.*]], 6
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 6
-; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false, !prof [[PROF4]]
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   switch i8 %f, label %bb1 [
@@ -517,7 +517,7 @@ define i1 @negative_range0to15(i8 range(i8 0, 16) %f) {
 ; CHECK-NEXT:      i8 6, label [[BB2:%.*]]
 ; CHECK-NEXT:      i8 7, label [[BB2]]
 ; CHECK-NEXT:      i8 14, label [[BB2]]
-; CHECK-NEXT:    ]
+; CHECK-NEXT:    ], !prof [[PROF6]]
 ; CHECK:       bb2:
 ; CHECK-NEXT:    br label [[BB3]]
 ; CHECK:       bb3:
@@ -544,7 +544,7 @@ define i1 @negative_range0to15_pow_2(i8 range(i8 0, 16) %f) {
 ; CHECK-NEXT:    [[TMP0:%.*]] = sub i8 [[F:%.*]], 6
 ; CHECK-NEXT:    [[SWITCH_AND:%.*]] = and i8 [[TMP0]], -2
 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i8 [[SWITCH_AND]], 0
-; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false, !prof [[PROF3]]
 ; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   switch i8 %f, label %bb1 [
@@ -566,7 +566,7 @@ define i1 @negative_range0to5even(i8 range(i8 0, 5) %f) {
 ; CHECK-NEXT:    [[TMP0:%.*]] = sub i8 [[F:%.*]], 2
 ; CHECK-NEXT:    [[SWITCH_AND:%.*]] = and i8 [[TMP0]], -3
 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i8 [[SWITCH_AND]], 0
-; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false, !prof [[PROF3]]
 ; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   switch i8 %f, label %bb1 [
@@ -586,7 +586,7 @@ define i1 @range0to15_corner_case(i8 range(i8 0, 16) %f) {
 ; CHECK-LABEL: @range0to15_corner_case(
 ; CHECK-NEXT:  bb3:
 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i8 [[F:%.*]], 15
-; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[COND]], i1 true, i1 false
+; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[COND]], i1 true, i1 false, !prof [[PROF9:![0-9]+]]
 ; CHECK-NEXT:    ret i1 [[DOT]]
 ;
   switch i8 %f, label %bb1 [
@@ -607,7 +607,7 @@ define i1 @negative_range0to15_corner_case(i8 range(i8 0, 16) %f) {
 ; CHECK-NEXT:    [[SWITCH_SELECTCMP_CASE1:%.*]] = icmp eq i8 [[F:%.*]], 15
 ; CHECK-NEXT:    [[SWITCH_SELECTCMP_CASE2:%.*]] = icmp eq i8 [[F]], 8
 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = or i1 [[SWITCH_SELECTCMP_CASE1]], [[SWITCH_SELECTCMP_CASE2]]
-; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false
+; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false, !prof [[PROF3]]
 ; CHECK-NEXT:    ret i1 [[TMP0]]
 ;
   switch i8 %f, label %bb1 [
@@ -631,7 +631,7 @@ define i1 @range0to15_out_of_range_non_prime(i8 range(i8 0, 16) %f) {
 ; CHECK-NEXT:  bb3:
 ; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[F:%.*]], 6
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 6
-; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false, !prof [[PROF4]]
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   switch i8 %f, label %bb1 [
@@ -655,7 +655,7 @@ define i1 @range0to15_out_of_range_non_prime_more(i8 range(i8 0, 16) %f) {
 ; CHECK-NEXT:  bb3:
 ; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[F:%.*]], 6
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 6
-; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false, !prof [[PROF4]]
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   switch i8 %f, label %bb1 [
@@ -681,7 +681,7 @@ define i1 @negative_range0to15_out_of_range_non_prime(i8 range(i8 0, 16) %f) {
 ; CHECK-NEXT:      i8 6, label [[BB2:%.*]]
 ; CHECK-NEXT:      i8 14, label [[BB2]]
 ; CHECK-NEXT:      i8 15, label [[BB2]]
-; CHECK-NEXT:    ]
+; CHECK-NEXT:    ], !prof [[PROF6]]
 ; CHECK:       bb2:
 ; CHECK-NEXT:    br label [[BB3]]
 ; CHECK:       bb3:
@@ -709,7 +709,7 @@ define i1 @negative_range0to15_out_of_range(i8 range(i8 0, 16) %f) {
 ; CHECK-NEXT:      i8 6, label [[BB2:%.*]]
 ; CHECK-NEXT: ...
[truncated]

@mtrofin mtrofin force-pushed the users/mtrofin/09-15-_profcheck_simplifycfg_propagate_prof_from_switch_to_select_ branch from 92728fa to 6d3342f Compare September 18, 2025 20:19
@mtrofin mtrofin requested a review from alanzhao1 September 18, 2025 23:02
Copy link
Contributor

@alanzhao1 alanzhao1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general this patch LGTM.

I noticed that one downside of using -profcheck-weights-for-test is that the original branch weights aren't in the test, so it's hard for me to understand how this change modifies the branch weights.

@mtrofin mtrofin force-pushed the users/mtrofin/09-15-_profcheck_simplifycfg_propagate_prof_from_switch_to_select_ branch from 6d3342f to 8027f03 Compare September 24, 2025 15:13
@mtrofin mtrofin force-pushed the users/mtrofin/09-18-_profcheck_option_to_inject_distinct_small_weights branch from c42de45 to 518490e Compare September 24, 2025 15:13
Copy link
Member Author

mtrofin commented Sep 24, 2025

In general this patch LGTM.

I noticed that one downside of using -profcheck-weights-for-test is that the original branch weights aren't in the test, so it's hard for me to understand how this change modifies the branch weights.

You're right. I think I'll just use -profcheck-weights-for-test "offline" to generate the .ll that is checked in. It's a convenience anyway - to avoid one having to write interesting profile metadata by hand in large tests. wdyt?

Base automatically changed from users/mtrofin/09-18-_profcheck_option_to_inject_distinct_small_weights to main September 24, 2025 18:40
@mtrofin mtrofin force-pushed the users/mtrofin/09-15-_profcheck_simplifycfg_propagate_prof_from_switch_to_select_ branch 3 times, most recently from bb09459 to a0452c3 Compare September 24, 2025 20:16
@mtrofin mtrofin requested a review from alanzhao1 September 24, 2025 20:18
@mtrofin mtrofin force-pushed the users/mtrofin/09-15-_profcheck_simplifycfg_propagate_prof_from_switch_to_select_ branch from a0452c3 to e277ce0 Compare September 25, 2025 00:31
@mtrofin mtrofin force-pushed the users/mtrofin/09-15-_profcheck_simplifycfg_propagate_prof_from_switch_to_select_ branch from e277ce0 to d9ac85c Compare September 25, 2025 00:34
Copy link
Member Author

mtrofin commented Sep 26, 2025

Merge activity

  • Sep 26, 9:15 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Sep 26, 9:16 PM UTC: @mtrofin merged this pull request with Graphite.

@mtrofin mtrofin merged commit d2f14bc into main Sep 26, 2025
9 checks passed
@mtrofin mtrofin deleted the users/mtrofin/09-15-_profcheck_simplifycfg_propagate_prof_from_switch_to_select_ branch September 26, 2025 21:16
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.

3 participants