-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[InstCombine] Fold icmp samesign u{gt/lt} (X +nsw C2), C -> icmp s{gt/lt} X, (C - C2)
#169960
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?
Conversation
|
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
|
@llvm/pr-subscribers-llvm-transforms Author: Tirthankar Mazumder (wermos) ChangesFixes #166973 Full diff: https://github.com/llvm/llvm-project/pull/169960.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 33eee8e059486..a707f1d2a056c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -28,6 +28,7 @@
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/IntrinsicsX86.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Transforms/InstCombine/InstCombiner.h"
@@ -3189,6 +3190,13 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
return new ICmpInst(ICmpInst::getSignedPredicate(Pred), X,
ConstantInt::get(Ty, C - *C2));
+ // Fold icmp samesign u{gt/ge/lt/le} (add nsw X, C2), C
+ // -> icmp s{gt/ge/lt/le} X, (C - C2)
+ CmpPredicate CP(Pred, Cmp.hasSameSign());
+ if (CP.hasSameSign() && Add->hasNoSignedWrap())
+ return new ICmpInst(CP.getPreferredSignedPredicate(), X,
+ ConstantInt::get(Ty, C - *C2));
+
auto CR = ConstantRange::makeExactICmpRegion(Pred, C).subtract(*C2);
const APInt &Upper = CR.getUpper();
const APInt &Lower = CR.getLower();
diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll
index 8449c7c5ea935..7c30337126b2b 100644
--- a/llvm/test/Transforms/InstCombine/icmp-add.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-add.ll
@@ -3440,3 +3440,15 @@ define i1 @val_is_aligend_pred_mismatch(i32 %num) {
%_0 = icmp sge i32 %num.masked, %num
ret i1 %_0
}
+
+define i1 @icmp_samesign_with_nsw_add(i32 %arg0) {
+; CHECK-LABEL: @icmp_samesign_with_nsw_add(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[V1:%.*]] = icmp sgt i32 [[ARG0:%.*]], 25
+; CHECK-NEXT: ret i1 [[V1]]
+;
+entry:
+ %v0 = add nsw i32 %arg0, -18
+ %v1 = icmp samesign ugt i32 %v0, 7
+ ret i1 %v1
+}
|
|
I'm not sure if I need to add more tests or not. Ping @dtcxzyw for enabling CI and code review |
icmp samesign u{gt/ge/lt/le} (X +nsw C2), C -> icmp s{gt/ge/lt/le} X, (C - C2)icmp samesign u{gt/ge/lt/le} (X +nsw C2), C -> icmp s{gt/ge/lt/le} X, (C - C2)
|
Good start is to look at https://llvm.org/docs/InstCombineContributorGuide.html there also is this old #134556 PR that is trying to solve the same thing that have comments that is not handled. |
|
Thanks for the pointers, I'll work on addressing those. |
Are you suggesting that I should modify that code to handle the samesign case as well? Since that code uses |
|
I ran into an interesting problem wherein my implemented transform is interfering with the transform added in #95649. That transform deals with the specific case where If I implement the transform where @andjo403 suggested, then tests like this: llvm-project/llvm/test/Transforms/InstCombine/icmp-add.ll Lines 3048 to 3057 in b228256
will get optimized differently. This happens because the add folding code I am adding comes before the power-of-2 folding code. So my question is, do we want to keep that power-of-2 behavior? If that is the case, then I will need to add extra conditions to the if-clause to prevent it from entering when |
|
I apologize for not having some code commits to go along with my previous comment, but I am working out some other unrelated kinks in my code, and I didn't want to unnecessarily confuse people. |
fe22d30 to
f197e46
Compare
|
sounds like a fault in your transform as the example that you give do not have samesign on the icmp so I do not think that it shall be affected by your transform |
|
Maybe is not so easy to combine the transforms in to one transform but add the new transform after the other and copy the parts that is needed for when samesign is used |
|
I've edited my topmost comment so it has an Alive2 proof link now. |
| // TODO: Can we assert there is no overflow because InstSimplify always | ||
| // handles those cases? |
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.
Can this comment be removed? If I understood this comment correctly, then it is obvious that there are cases where an overflow can happen, so this defensive code is needed. Specifically, the @icmp_samesign_with_nsw_add_neg test causes a ssub overflow to happen.
icmp samesign u{gt/ge/lt/le} (X +nsw C2), C -> icmp s{gt/ge/lt/le} X, (C - C2)icmp samesign u{gt/lt} (X +nsw C2), C -> icmp s{gt/lt} X, (C - C2)
🐧 Linux x64 Test Results
Failed Tests(click on a test name to see its output) LLVMLLVM.Transforms/InstCombine/remove-loop-phi-multiply-by-zero.llIf these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the |
|
Should I run |
|
you need to run update_test_check.py on that file also but it show a test that you are missing where the add is "add nuw nsw" so the same comment as in #134556 (comment) |
Is there a reason we give higher priority to the case where the add is unsigned? |
|
unsigned is the more canonical form |
… (C - C2)` whenever applicable.
|
I haven't handled the nuw + nsw case yet, I'll do that later because I am traveling right now. |
Fixes #166973
Partially addresses #134028
Alive2 proof: https://alive2.llvm.org/ce/z/BqHQNN