-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[InstCombine] Fold max/min when incrementing/decrementing by 1 #142466
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
Changes from 7 commits
1257dca
def4aeb
675aaff
7d41d85
ffdcb9b
00d8f91
5d6aba5
aea0343
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 | ||||
|---|---|---|---|---|---|---|
|
|
@@ -565,6 +565,59 @@ Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal, | |||||
| return nullptr; | ||||||
| } | ||||||
|
|
||||||
| /// Try to fold a select to a min/max intrinsic. Many cases are already handled | ||||||
| /// by matchDecomposedSelectPattern but here we handle the cases where more | ||||||
| /// exensive modification of the IR is required. | ||||||
| static Value *foldSelectICmpMinMax(const ICmpInst *Cmp, Value *TVal, | ||||||
| Value *FVal, | ||||||
| InstCombiner::BuilderTy &Builder, | ||||||
| const SimplifyQuery &SQ) { | ||||||
| const Value *CmpLHS = Cmp->getOperand(0); | ||||||
| const Value *CmpRHS = Cmp->getOperand(1); | ||||||
| ICmpInst::Predicate Pred = Cmp->getPredicate(); | ||||||
|
|
||||||
| // (X > Y) ? X : (Y - 1) ==> MIN(X, Y - 1) | ||||||
| // (X < Y) ? X : (Y + 1) ==> MAX(X, Y + 1) | ||||||
| // This transformation is valid when overflow corresponding to the sign of | ||||||
| // the comparison is poison and we must drop the non-matching overflow flag. | ||||||
| if (CmpRHS == TVal) { | ||||||
| std::swap(CmpLHS, CmpRHS); | ||||||
| Pred = CmpInst::getSwappedPredicate(Pred); | ||||||
| } | ||||||
|
|
||||||
| // TODO: consider handeling 'or disjoint' as well, though these would need to | ||||||
|
||||||
| // TODO: consider handeling 'or disjoint' as well, though these would need to | |
| // TODO: consider handling 'or disjoint' as well, though these would need to |
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.
Fixed
Outdated
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.
Early exit?
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.
Sounds good. Updated.
dtcxzyw marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Outdated
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.
| // canonicalize to "add %x, -1" discarding the nuw flag. | |
| // canonicalized to "add %x, -1" discarding the nuw flag. |
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.
Fixed
Outdated
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.
In this case the nuw flag is also invalid: https://alive2.llvm.org/ce/z/ZpSaKv
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.
Updated. In practice, I'm not sure we could ever reach this point in that case, at least I was not able to construct a test. But I agree it is good to stay on the safe side and not rely on unrelated optimizations to prevent a mis-compilation here.
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.
extensive?
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.
Fixed