[llvm] [InstCombine] Set !prof metadata on Selects identified by add.ll test (PR #158743)
Alan Zhao via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 17 15:47:59 PDT 2025
https://github.com/alanzhao1 updated https://github.com/llvm/llvm-project/pull/158743
>From 2f5c4f8f945309219c06ed312b0cbfdfa10af532 Mon Sep 17 00:00:00 2001
From: Alan Zhao <ayzhao at google.com>
Date: Mon, 15 Sep 2025 14:41:42 -0700
Subject: [PATCH 1/3] [InstCombine] Set !prof metadata on Selects identified by
add.ll test
These select instructions are created from non-branching instructions,
so their branch weights are unknown.
Tracking issue: #147390
---
.../InstCombine/InstCombineAddSub.cpp | 10 ++++-
.../InstCombine/InstCombineShifts.cpp | 5 ++-
.../InstCombine/InstructionCombining.cpp | 5 ++-
.../InstCombine/preserve-profile.ll | 39 +++++++++++++++++++
llvm/utils/profcheck-xfail.txt | 2 -
5 files changed, 55 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 00951fde0cf8a..a480d96cd4cb9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -24,6 +24,7 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/ProfDataUtils.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/AlignOf.h"
@@ -878,13 +879,18 @@ Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
return BinaryOperator::CreateAdd(Builder.CreateNot(Y), X);
// zext(bool) + C -> bool ? C + 1 : C
+ SelectInst *SI = nullptr;
if (match(Op0, m_ZExt(m_Value(X))) &&
X->getType()->getScalarSizeInBits() == 1)
- return SelectInst::Create(X, InstCombiner::AddOne(Op1C), Op1);
+ SI = SelectInst::Create(X, InstCombiner::AddOne(Op1C), Op1);
// sext(bool) + C -> bool ? C - 1 : C
if (match(Op0, m_SExt(m_Value(X))) &&
X->getType()->getScalarSizeInBits() == 1)
- return SelectInst::Create(X, InstCombiner::SubOne(Op1C), Op1);
+ SI = SelectInst::Create(X, InstCombiner::SubOne(Op1C), Op1);
+ if (SI) {
+ setExplicitlyUnknownBranchWeights(*SI, DEBUG_TYPE);
+ return SI;
+ }
// ~X + C --> (C-1) - X
if (match(Op0, m_Not(m_Value(X)))) {
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 550f095b26ba4..247f1483e14f5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -14,6 +14,7 @@
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/ProfDataUtils.h"
#include "llvm/Transforms/InstCombine/InstCombiner.h"
using namespace llvm;
using namespace PatternMatch;
@@ -1253,7 +1254,9 @@ Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
// shl (zext i1 X), C1 --> select (X, 1 << C1, 0)
if (match(Op0, m_ZExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) {
auto *NewC = Builder.CreateShl(ConstantInt::get(Ty, 1), C1);
- return SelectInst::Create(X, NewC, ConstantInt::getNullValue(Ty));
+ auto *SI = SelectInst::Create(X, NewC, ConstantInt::getNullValue(Ty));
+ setExplicitlyUnknownBranchWeights(*SI, DEBUG_TYPE);
+ return SI;
}
}
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index f0ddd5ca94c5a..957f8bd588857 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -81,6 +81,7 @@
#include "llvm/IR/Operator.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/ProfDataUtils.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
@@ -1735,7 +1736,9 @@ Instruction *InstCombinerImpl::foldBinopOfSextBoolToSelect(BinaryOperator &BO) {
Constant *Zero = ConstantInt::getNullValue(BO.getType());
Value *TVal = Builder.CreateBinOp(BO.getOpcode(), Ones, C);
Value *FVal = Builder.CreateBinOp(BO.getOpcode(), Zero, C);
- return SelectInst::Create(X, TVal, FVal);
+ SelectInst *SI = SelectInst::Create(X, TVal, FVal);
+ setExplicitlyUnknownBranchWeights(*SI, DEBUG_TYPE);
+ return SI;
}
static Value *simplifyOperationIntoSelectOperand(Instruction &I, SelectInst *SI,
diff --git a/llvm/test/Transforms/InstCombine/preserve-profile.ll b/llvm/test/Transforms/InstCombine/preserve-profile.ll
index dd83805ed3397..0b750fd87d641 100644
--- a/llvm/test/Transforms/InstCombine/preserve-profile.ll
+++ b/llvm/test/Transforms/InstCombine/preserve-profile.ll
@@ -46,9 +46,48 @@ define i32 @NegBin(i1 %C) !prof !0 {
ret i32 %V
}
+define i32 @select_C_minus_1_or_C_from_bool(i1 %x) {
+; CHECK-LABEL: define i32 @select_C_minus_1_or_C_from_bool(
+; CHECK-SAME: i1 [[X:%.*]]) {
+; CHECK-NEXT: [[ADD:%.*]] = select i1 [[X]], i32 41, i32 42, !prof [[PROF2:![0-9]+]]
+; CHECK-NEXT: ret i32 [[ADD]]
+;
+ %ext = sext i1 %x to i32
+ %add = add i32 %ext, 42
+ ret i32 %add
+}
+
+define i5 @and_add(i1 %x, i1 %y) {
+; CHECK-LABEL: define i5 @and_add(
+; CHECK-SAME: i1 [[X:%.*]], i1 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X]], true
+; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[Y]], [[TMP1]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i5 -2, i5 0, !prof [[PROF2]]
+; CHECK-NEXT: ret i5 [[R]]
+;
+ %xz = zext i1 %x to i5
+ %ys = sext i1 %y to i5
+ %sub = add i5 %xz, %ys
+ %r = and i5 %sub, 30
+ ret i5 %r
+}
+
+define i32 @add_zext_zext_i1(i1 %a) {
+; CHECK-LABEL: define i32 @add_zext_zext_i1(
+; CHECK-SAME: i1 [[A:%.*]]) {
+; CHECK-NEXT: [[ADD:%.*]] = select i1 [[A]], i32 2, i32 0, !prof [[PROF2]]
+; CHECK-NEXT: ret i32 [[ADD]]
+;
+ %zext = zext i1 %a to i32
+ %add = add i32 %zext, %zext
+ ret i32 %add
+}
+
+
!0 = !{!"function_entry_count", i64 1000}
!1 = !{!"branch_weights", i32 2, i32 3}
;.
; CHECK: [[PROF0]] = !{!"function_entry_count", i64 1000}
; CHECK: [[PROF1]] = !{!"branch_weights", i32 2, i32 3}
+; CHECK: [[PROF2]] = !{!"unknown", !"instcombine"}
;.
diff --git a/llvm/utils/profcheck-xfail.txt b/llvm/utils/profcheck-xfail.txt
index 482848842aa05..582bb42315ac7 100644
--- a/llvm/utils/profcheck-xfail.txt
+++ b/llvm/utils/profcheck-xfail.txt
@@ -836,8 +836,6 @@ Transforms/InstCombine/2011-02-14-InfLoop.ll
Transforms/InstCombine/AArch64/sve-intrinsic-sel.ll
Transforms/InstCombine/AArch64/sve-intrinsic-simplify-binop.ll
Transforms/InstCombine/AArch64/sve-intrinsic-simplify-shift.ll
-Transforms/InstCombine/add2.ll
-Transforms/InstCombine/add.ll
Transforms/InstCombine/add-mask.ll
Transforms/InstCombine/add-shl-mul-umax.ll
Transforms/InstCombine/add-shl-sdiv-to-srem.ll
>From b42e0c5b625794a328ed1f3d31602002995369a6 Mon Sep 17 00:00:00 2001
From: Alan Zhao <ayzhao at google.com>
Date: Mon, 15 Sep 2025 18:42:29 -0700
Subject: [PATCH 2/3] add check for !SI
---
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index a480d96cd4cb9..d97ff07a9312a 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -884,7 +884,7 @@ Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
X->getType()->getScalarSizeInBits() == 1)
SI = SelectInst::Create(X, InstCombiner::AddOne(Op1C), Op1);
// sext(bool) + C -> bool ? C - 1 : C
- if (match(Op0, m_SExt(m_Value(X))) &&
+ if (!SI && match(Op0, m_SExt(m_Value(X))) &&
X->getType()->getScalarSizeInBits() == 1)
SI = SelectInst::Create(X, InstCombiner::SubOne(Op1C), Op1);
if (SI) {
>From cc4e8b4b18ce587db56c827495d6f1929d5f3c6d Mon Sep 17 00:00:00 2001
From: Alan Zhao <ayzhao at google.com>
Date: Wed, 17 Sep 2025 15:47:41 -0700
Subject: [PATCH 3/3] add profile unknown only if the enclosing function has
profile counts
---
llvm/include/llvm/IR/ProfDataUtils.h | 8 +++++++
llvm/lib/IR/ProfDataUtils.cpp | 10 ++++++++
.../InstCombine/InstCombineAddSub.cpp | 2 +-
.../InstCombine/InstCombineShifts.cpp | 2 +-
.../InstCombine/InstructionCombining.cpp | 2 +-
.../InstCombine/preserve-profile.ll | 23 ++++++++++++++-----
6 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/llvm/include/llvm/IR/ProfDataUtils.h b/llvm/include/llvm/IR/ProfDataUtils.h
index de9675f48c79b..c39ebe5b682bc 100644
--- a/llvm/include/llvm/IR/ProfDataUtils.h
+++ b/llvm/include/llvm/IR/ProfDataUtils.h
@@ -185,6 +185,14 @@ inline uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale) {
LLVM_ABI void setExplicitlyUnknownBranchWeights(Instruction &I,
StringRef PassName);
+/// Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch
+/// weights in the new instruction if the parent function of the original
+/// instruction has function counts. This is to not confuse users by injecting
+/// profile data into non-profiled functions.
+LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &New,
+ Instruction &Original,
+ StringRef PassName);
+
/// Analogous to setExplicitlyUnknownBranchWeights, but for functions and their
/// entry counts.
LLVM_ABI void setExplicitlyUnknownFunctionEntryCount(Function &F,
diff --git a/llvm/lib/IR/ProfDataUtils.cpp b/llvm/lib/IR/ProfDataUtils.cpp
index 5827292cee39b..a3e8f03b252e9 100644
--- a/llvm/lib/IR/ProfDataUtils.cpp
+++ b/llvm/lib/IR/ProfDataUtils.cpp
@@ -252,6 +252,16 @@ void setExplicitlyUnknownBranchWeights(Instruction &I, StringRef PassName) {
MDB.createString(PassName)}));
}
+void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &New,
+ Instruction &Original,
+ StringRef PassName) {
+ Function *F = Original.getFunction();
+ assert(F && "instruction does not belong to a function!");
+ std::optional<Function::ProfileCount> EC = F->getEntryCount();
+ if (EC && EC->getCount() > 0)
+ setExplicitlyUnknownBranchWeights(New, PassName);
+}
+
void setExplicitlyUnknownFunctionEntryCount(Function &F, StringRef PassName) {
MDBuilder MDB(F.getContext());
F.setMetadata(
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index d97ff07a9312a..855fd00e9bf83 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -888,7 +888,7 @@ Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
X->getType()->getScalarSizeInBits() == 1)
SI = SelectInst::Create(X, InstCombiner::SubOne(Op1C), Op1);
if (SI) {
- setExplicitlyUnknownBranchWeights(*SI, DEBUG_TYPE);
+ setExplicitlyUnknownBranchWeightsIfProfiled(*SI, Add, DEBUG_TYPE);
return SI;
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 247f1483e14f5..0a111d5befd79 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -1255,7 +1255,7 @@ Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
if (match(Op0, m_ZExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) {
auto *NewC = Builder.CreateShl(ConstantInt::get(Ty, 1), C1);
auto *SI = SelectInst::Create(X, NewC, ConstantInt::getNullValue(Ty));
- setExplicitlyUnknownBranchWeights(*SI, DEBUG_TYPE);
+ setExplicitlyUnknownBranchWeightsIfProfiled(*SI, I, DEBUG_TYPE);
return SI;
}
}
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 957f8bd588857..b39aa44379514 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1737,7 +1737,7 @@ Instruction *InstCombinerImpl::foldBinopOfSextBoolToSelect(BinaryOperator &BO) {
Value *TVal = Builder.CreateBinOp(BO.getOpcode(), Ones, C);
Value *FVal = Builder.CreateBinOp(BO.getOpcode(), Zero, C);
SelectInst *SI = SelectInst::Create(X, TVal, FVal);
- setExplicitlyUnknownBranchWeights(*SI, DEBUG_TYPE);
+ setExplicitlyUnknownBranchWeightsIfProfiled(*SI, BO, DEBUG_TYPE);
return SI;
}
diff --git a/llvm/test/Transforms/InstCombine/preserve-profile.ll b/llvm/test/Transforms/InstCombine/preserve-profile.ll
index 0b750fd87d641..8cb3e685ae302 100644
--- a/llvm/test/Transforms/InstCombine/preserve-profile.ll
+++ b/llvm/test/Transforms/InstCombine/preserve-profile.ll
@@ -46,9 +46,9 @@ define i32 @NegBin(i1 %C) !prof !0 {
ret i32 %V
}
-define i32 @select_C_minus_1_or_C_from_bool(i1 %x) {
+define i32 @select_C_minus_1_or_C_from_bool(i1 %x) !prof !0 {
; CHECK-LABEL: define i32 @select_C_minus_1_or_C_from_bool(
-; CHECK-SAME: i1 [[X:%.*]]) {
+; CHECK-SAME: i1 [[X:%.*]]) !prof [[PROF0]] {
; CHECK-NEXT: [[ADD:%.*]] = select i1 [[X]], i32 41, i32 42, !prof [[PROF2:![0-9]+]]
; CHECK-NEXT: ret i32 [[ADD]]
;
@@ -57,9 +57,9 @@ define i32 @select_C_minus_1_or_C_from_bool(i1 %x) {
ret i32 %add
}
-define i5 @and_add(i1 %x, i1 %y) {
+define i5 @and_add(i1 %x, i1 %y) !prof !0 {
; CHECK-LABEL: define i5 @and_add(
-; CHECK-SAME: i1 [[X:%.*]], i1 [[Y:%.*]]) {
+; CHECK-SAME: i1 [[X:%.*]], i1 [[Y:%.*]]) !prof [[PROF0]] {
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X]], true
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[Y]], [[TMP1]]
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i5 -2, i5 0, !prof [[PROF2]]
@@ -72,9 +72,9 @@ define i5 @and_add(i1 %x, i1 %y) {
ret i5 %r
}
-define i32 @add_zext_zext_i1(i1 %a) {
+define i32 @add_zext_zext_i1(i1 %a) !prof !0 {
; CHECK-LABEL: define i32 @add_zext_zext_i1(
-; CHECK-SAME: i1 [[A:%.*]]) {
+; CHECK-SAME: i1 [[A:%.*]]) !prof [[PROF0]] {
; CHECK-NEXT: [[ADD:%.*]] = select i1 [[A]], i32 2, i32 0, !prof [[PROF2]]
; CHECK-NEXT: ret i32 [[ADD]]
;
@@ -83,6 +83,17 @@ define i32 @add_zext_zext_i1(i1 %a) {
ret i32 %add
}
+define i32 @no_count_no_branch_weights(i1 %a) {
+; CHECK-LABEL: define i32 @no_count_no_branch_weights(
+; CHECK-SAME: i1 [[A:%.*]]) {
+; CHECK-NEXT: [[ADD:%.*]] = select i1 [[A]], i32 2, i32 0
+; CHECK-NEXT: ret i32 [[ADD]]
+;
+ %zext = zext i1 %a to i32
+ %add = add i32 %zext, %zext
+ ret i32 %add
+}
+
!0 = !{!"function_entry_count", i64 1000}
!1 = !{!"branch_weights", i32 2, i32 3}
More information about the llvm-commits
mailing list