-
Notifications
You must be signed in to change notification settings - Fork 15k
[InstCombine] Preserve profile data with select instructions and binary operators #158375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
5ac86b7
cad50aa
938a4d4
5d7169e
701bf31
fe929d4
d2979b4
52d9c46
d8731d3
dfbd3f3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -1361,6 +1363,8 @@ Value *InstCombinerImpl::SimplifySelectsFeedingBinaryOp(BinaryOperator &I, | |
if (!LHSIsSelect && !RHSIsSelect) | ||
return nullptr; | ||
|
||
SelectInst *SI = cast<SelectInst>(LHSIsSelect ? LHS : RHS); | ||
|
||
FastMathFlags FMF; | ||
BuilderTy::FastMathFlagGuard Guard(Builder); | ||
if (isa<FPMathOperator>(&I)) { | ||
|
@@ -1381,15 +1385,14 @@ 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; | ||
if (True && match(FVal, m_Neg(m_Value(N)))) { | ||
Value *Sub = Builder.CreateSub(Z, N); | ||
return Builder.CreateSelect(Cond, True, Sub, I.getName()); | ||
return Builder.CreateSelect(Cond, True, Sub, I.getName(), SI); | ||
} | ||
if (False && match(TVal, m_Neg(m_Value(N)))) { | ||
Value *Sub = Builder.CreateSub(Z, N); | ||
return Builder.CreateSelect(Cond, Sub, False, I.getName()); | ||
return Builder.CreateSelect(Cond, Sub, False, I.getName(), SI); | ||
} | ||
return nullptr; | ||
}; | ||
|
@@ -1399,6 +1402,11 @@ 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there something we could assert? like maybe that the fraction is the same... albeit that's float point comparison, ugh... ok, how about a ORE message about what the 2 were, or LLVM_DEBUG, just so we can easily introspect if we ever need to. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added an assertion that left and right profiles should be equal. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there are 2 cases where the pointers won't be the same:
IDK, may be safer to LLVM_DEBUG. The assert may get someone on a wild goose chase in the cases above. Or add a comment above it that we don't expect those cases to happen, but if they do, safe to replace the assert w a LLVM_DEBUG or something of the sort. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no IR validity constraint that branch weight metadata has to "make sense", so you also can't assert that here. |
||
// the same idempotent conditional. | ||
assert(cast<SelectInst>(LHS)->getMetadata(LLVMContext::MD_prof) == | ||
cast<SelectInst>(RHS)->getMetadata(LLVMContext::MD_prof) && | ||
"LHS and RHS select statements have different metadata!"); | ||
|
||
if (LHS->hasOneUse() && RHS->hasOneUse()) { | ||
if (False && !True) | ||
|
@@ -1425,9 +1433,9 @@ Value *InstCombinerImpl::SimplifySelectsFeedingBinaryOp(BinaryOperator &I, | |
if (!True || !False) | ||
return nullptr; | ||
|
||
Value *SI = Builder.CreateSelect(Cond, True, False); | ||
SI->takeName(&I); | ||
return SI; | ||
Value *NewSI = Builder.CreateSelect(Cond, True, False, I.getName(), SI); | ||
NewSI->takeName(&I); | ||
return NewSI; | ||
} | ||
|
||
/// Freely adapt every user of V as-if V was changed to !V. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 6 | ||
; RUN: opt < %s -passes=instcombine -S | FileCheck %s | ||
alanzhao1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
define i32 @LHSBin(i1 %C) !prof !0 { | ||
; CHECK-LABEL: define i32 @LHSBin( | ||
; CHECK-SAME: i1 [[C:%.*]]) !prof [[PROF0:![0-9]+]] { | ||
; CHECK-NEXT: [[V:%.*]] = select i1 [[C]], i32 1010, i32 20, !prof [[PROF1:![0-9]+]] | ||
; CHECK-NEXT: ret i32 [[V]] | ||
; | ||
%A = select i1 %C, i32 1000, i32 10, !prof !1 | ||
%V = add i32 %A, 10 | ||
ret i32 %V | ||
} | ||
|
||
define i32 @RHSBin(i1 %C) !prof !0 { | ||
; CHECK-LABEL: define i32 @RHSBin( | ||
; CHECK-SAME: i1 [[C:%.*]]) !prof [[PROF0]] { | ||
; CHECK-NEXT: [[V:%.*]] = select i1 [[C]], i32 1010, i32 20, !prof [[PROF1]] | ||
; CHECK-NEXT: ret i32 [[V]] | ||
; | ||
%A = select i1 %C, i32 1000, i32 10, !prof !1 | ||
%V = add i32 10, %A | ||
ret i32 %V; | ||
} | ||
|
||
define i32 @BothBin(i1 %C) !prof !0 { | ||
; CHECK-LABEL: define i32 @BothBin( | ||
; CHECK-SAME: i1 [[C:%.*]]) !prof [[PROF0]] { | ||
; CHECK-NEXT: [[V:%.*]] = select i1 [[C]], i32 2000, i32 20, !prof [[PROF1]] | ||
; CHECK-NEXT: ret i32 [[V]] | ||
; | ||
%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; | ||
} | ||
|
||
define i32 @NegBin(i1 %C) !prof !0 { | ||
; CHECK-LABEL: define i32 @NegBin( | ||
; CHECK-SAME: i1 [[C:%.*]]) !prof [[PROF0]] { | ||
; CHECK-NEXT: [[V:%.*]] = select i1 [[C]], i32 1010, i32 0, !prof [[PROF1]] | ||
; CHECK-NEXT: ret i32 [[V]] | ||
; | ||
%A = select i1 %C, i32 1000, i32 -10, !prof !1 | ||
%V = add i32 %A, 10 | ||
ret i32 %V | ||
} | ||
|
||
!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} | ||
;. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused, should be dropped.