Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

alanzhao1
Copy link
Contributor

Tracking issue: #147390

@alanzhao1 alanzhao1 requested a review from mtrofin September 12, 2025 22:07
@alanzhao1 alanzhao1 requested a review from nikic as a code owner September 12, 2025 22:07
@llvmbot llvmbot added llvm:instcombine Covers the InstCombine, InstSimplify and AggressiveInstCombine passes llvm:transforms labels Sep 12, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 12, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Alan Zhao (alanzhao1)

Changes

Tracking issue: #147390


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

2 Files Affected:

  • (modified) llvm/lib/Transforms/InstCombine/InstructionCombining.cpp (+16-5)
  • (added) llvm/test/Transforms/InstCombine/preserve-profile.ll (+40)
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index c2f045a2ab02e..4f4d533262006 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -144,6 +144,8 @@ static cl::opt<unsigned>
 MaxArraySize("instcombine-maxarray-size", cl::init(1024),
              cl::desc("Maximum array size considered when doing a combine"));
 
+extern cl::opt<bool> ProfcheckDisableMetadataFixes;      
+
 // FIXME: Remove this flag when it is no longer necessary to convert
 // llvm.dbg.declare to avoid inaccurate debug info. Setting this to false
 // increases variable availability at the cost of accuracy. Variables that
@@ -1372,6 +1374,7 @@ Value *InstCombinerImpl::SimplifySelectsFeedingBinaryOp(BinaryOperator &I,
   SimplifyQuery Q = SQ.getWithInstruction(&I);
 
   Value *Cond, *True = nullptr, *False = nullptr;
+  MDNode *ProfileData;
 
   // Special-case for add/negate combination. Replace the zero in the negation
   // with the trailing add operand:
@@ -1381,17 +1384,18 @@ Value *InstCombinerImpl::SimplifySelectsFeedingBinaryOp(BinaryOperator &I,
     // We need an 'add' and exactly 1 arm of the select to have been simplified.
     if (Opcode != Instruction::Add || (!True && !False) || (True && False))
       return nullptr;
-
-    Value *N;
+    Value *N, *SI = nullptr;
     if (True && match(FVal, m_Neg(m_Value(N)))) {
       Value *Sub = Builder.CreateSub(Z, N);
-      return Builder.CreateSelect(Cond, True, Sub, I.getName());
+      SI = Builder.CreateSelect(Cond, True, Sub, I.getName());
     }
     if (False && match(TVal, m_Neg(m_Value(N)))) {
       Value *Sub = Builder.CreateSub(Z, N);
-      return Builder.CreateSelect(Cond, Sub, False, I.getName());
+      SI = Builder.CreateSelect(Cond, Sub, False, I.getName());
     }
-    return nullptr;
+    if (!ProfcheckDisableMetadataFixes && !SI)
+      cast<SelectInst>(SI)->setMetadata(LLVMContext::MD_prof, ProfileData);
+    return SI;
   };
 
   if (LHSIsSelect && RHSIsSelect && A == D) {
@@ -1399,6 +1403,9 @@ Value *InstCombinerImpl::SimplifySelectsFeedingBinaryOp(BinaryOperator &I,
     Cond = A;
     True = simplifyBinOp(Opcode, B, E, FMF, Q);
     False = simplifyBinOp(Opcode, C, F, FMF, Q);
+    // Profile weights for both LHS and RHS should be the same because they have
+    // the same idempotent conditional.
+    ProfileData = cast<SelectInst>(LHS)->getMetadata(LLVMContext::MD_prof);
 
     if (LHS->hasOneUse() && RHS->hasOneUse()) {
       if (False && !True)
@@ -1408,6 +1415,7 @@ Value *InstCombinerImpl::SimplifySelectsFeedingBinaryOp(BinaryOperator &I,
     }
   } else if (LHSIsSelect && LHS->hasOneUse()) {
     // (A ? B : C) op Y -> A ? (B op Y) : (C op Y)
+    ProfileData = cast<SelectInst>(LHS)->getMetadata(LLVMContext::MD_prof);
     Cond = A;
     True = simplifyBinOp(Opcode, B, RHS, FMF, Q);
     False = simplifyBinOp(Opcode, C, RHS, FMF, Q);
@@ -1415,6 +1423,7 @@ Value *InstCombinerImpl::SimplifySelectsFeedingBinaryOp(BinaryOperator &I,
       return NewSel;
   } else if (RHSIsSelect && RHS->hasOneUse()) {
     // X op (D ? E : F) -> D ? (X op E) : (X op F)
+    ProfileData = cast<SelectInst>(RHS)->getMetadata(LLVMContext::MD_prof);
     Cond = D;
     True = simplifyBinOp(Opcode, LHS, E, FMF, Q);
     False = simplifyBinOp(Opcode, LHS, F, FMF, Q);
@@ -1427,6 +1436,8 @@ Value *InstCombinerImpl::SimplifySelectsFeedingBinaryOp(BinaryOperator &I,
 
   Value *SI = Builder.CreateSelect(Cond, True, False);
   SI->takeName(&I);
+  if (!ProfcheckDisableMetadataFixes)
+    cast<SelectInst>(SI)->setMetadata(LLVMContext::MD_prof, ProfileData);
   return SI;
 }
 
diff --git a/llvm/test/Transforms/InstCombine/preserve-profile.ll b/llvm/test/Transforms/InstCombine/preserve-profile.ll
new file mode 100644
index 0000000000000..47254a88b1ed1
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/preserve-profile.ll
@@ -0,0 +1,40 @@
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+; CHECK: define i32 @LHSBin(i1 %C) !prof ![[PROF0:[0-9]]]
+; CHECK: %V = select i1 %C, i32 1010, i32 20, !prof ![[PROF1:[0-9]]]
+define i32 @LHSBin(i1 %C) !prof !0 {
+  %A = select i1 %C, i32 1000, i32 10, !prof !1
+  %V = add i32 %A, 10
+  ret i32 %V
+}
+
+; CHECK: define i32 @RHSBin(i1 %C) !prof ![[PROF0]]
+; CHECK: %V = select i1 %C, i32 1010, i32 20, !prof ![[PROF1]]
+define i32 @RHSBin(i1 %C) !prof !0 {
+  %A = select i1 %C, i32 1000, i32 10, !prof !1
+  %V = add i32 10, %A
+  ret i32 %V;
+}
+
+; CHECK: define i32 @BothBin(i1 %C) !prof ![[PROF0]]
+; CHECK: %V = select i1 %C, i32 2000, i32 20, !prof ![[PROF1]]
+define i32 @BothBin(i1 %C) !prof !0 {
+  %A = select i1 %C, i32 1000, i32 10, !prof !1
+  %B = select i1 %C, i32 1000, i32 10, !prof !1
+  %V = add i32 %A, %B
+  ret i32 %V;
+}
+
+; CHECK: define i32 @NegBin(i1 %C) !prof ![[PROF0:[0-9]]]
+; CHECK: %V = select i1 %C, i32 1010, i32 0, !prof ![[PROF1:[0-9]]]
+define i32 @NegBin(i1 %C) !prof !0 {
+  %A = select i1 %C, i32 1000, i32 -10, !prof !1
+  %V = add i32 %A, 10
+  ret i32 %V
+}
+
+
+; CHECK: ![[PROF0]] = !{!"function_entry_count", i64 1000}
+; CHECK: ![[PROF1]] = !{!"branch_weights", i32 2, i32 3}
+!0 = !{!"function_entry_count", i64 1000}
+!1 = !{!"branch_weights", i32 2, i32 3}

Copy link

github-actions bot commented Sep 12, 2025

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

Copy link
Member

@mtrofin mtrofin left a comment

Choose a reason for hiding this comment

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

lgtm - ptal my note about asserting on metadata equality

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:instcombine Covers the InstCombine, InstSimplify and AggressiveInstCombine passes llvm:transforms
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants