-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
[InstCombine] Treat umax as select(icmp eq x, 0), 1, x) in binop select fold. #65978
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-llvm-transforms ChangesThere is an existing instcombine in SimplifySelectsFeedingBinaryOp for folding
|
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.
Why is this specific to umin(1)? Doesn't the same work for, say, umin(2)? https://alive2.llvm.org/ce/z/gQqtpt
Or really any min/max intrinsic decomposed into select form.
Hi - thanks for taking a look and sorry this took a while to get back to. This was causing some regressions in my motivating case due to knock-on register allocation. That should hopefully be resolved now and so it leads to an improvement as you would expect. I've been looking at trying to generalize it to more cases and deal with the undef. I'll update this patch with the more special case, which the general case can be added to but is more complex. I think I have it working, but have to check through some of the details. Unfortunately it appears some cases are not valid with undef arguments. I've tried to limit it to valid cases (as opposed to adding freeze). I know that undef can be odd at times but I'm not sure it should be this odd. |
…ct fold. There is an existing instcombine for folding: `(A ? B : C) binop (A ? E : F) -> A ? (B binop E) : (C binop F)`. However this will not combine if the select `(x>=1 ? x : 1)` has been converted to a `umax(x, 1)`. This adds code to treat the umax as a select, allowing binops to fold into the select. This patch handles the more special case where the predicate is the limit extreme (such as `x==0 ? x : 1`), meaning it will use a ==0 predicate as opposed to the >= predicate usually applied to a umax. According to alive this is valid so long as the variables are not undef, are known to be non-equal (https://alive2.llvm.org/ce/z/VAYw3J) or known to be the same value (https://alive2.llvm.org/ce/z/4TSd7v). Here are some proofs for different min/maxes: umax: https://alive2.llvm.org/ce/z/kLw4J9 umin: https://alive2.llvm.org/ce/z/nvPa7p smin: https://alive2.llvm.org/ce/z/HS8V7V smax: https://alive2.llvm.org/ce/z/D2ocju
8883173
to
dcf0716
Compare
This is a generalization to the code added in llvm#65978, attempting to handle more with predicates and min/max that match. It was originally trying to use matchDecomposedSelectPattern but I replaced that with just checking the predicates and SPF match. The opposite conditions are also handled, which just inverts the order of the E/F variables. TODO: Add some proofs.
The more general cases will hopefully be something like davemgreen@7ba90fb. |
I'm not a fan of the special undef handling here. We should either insert the necessary freeze, or, if that covers your motivating case, we can start with guarding the transform under isGuaranteedNotToBeUndefOrPoison(). |
There is an existing instcombine for folding:
(A ? B : C) binop (A ? E : F) -> A ? (B binop E) : (C binop F)
.However this will not combine if the select
(x>=1 ? x : 1)
hasbeen converted to a
umax(x, 1)
. This adds code to treat the umaxas a select, allowing binops to fold into the select.
This patch handles the more special case where the predicate is the limit
extreme (such as
x==0 ? x : 1
), meaning it will use a ==0 predicate asopposed to the >= predicate usually applied to a umax. According to alive this
is valid so long as the variables are not undef, are known to be non-equal
(https://alive2.llvm.org/ce/z/VAYw3J) or known to be the same value
(https://alive2.llvm.org/ce/z/4TSd7v).
Here are some proofs for different min/maxes:
umax: https://alive2.llvm.org/ce/z/kLw4J9
umin: https://alive2.llvm.org/ce/z/nvPa7p
smin: https://alive2.llvm.org/ce/z/HS8V7V
smax: https://alive2.llvm.org/ce/z/D2ocju