-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[InstCombine] Relax the one-use constraints for icmp pred (binop X, Z), (binop Y, Z)
#76384
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
Conversation
@llvm/pr-subscribers-llvm-transforms Author: Yingwei Zheng (dtcxzyw) ChangesThis patch relaxes the one-use constraints for
Full diff: https://github.com/llvm/llvm-project/pull/76384.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 289976718e52f3..0afb415a482411 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -4911,8 +4911,8 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
}
}
- if (BO0 && BO1 && BO0->getOpcode() == BO1->getOpcode() && BO0->hasOneUse() &&
- BO1->hasOneUse() && BO0->getOperand(1) == BO1->getOperand(1)) {
+ if (BO0 && BO1 && BO0->getOpcode() == BO1->getOpcode() &&
+ BO0->getOperand(1) == BO1->getOperand(1)) {
switch (BO0->getOpcode()) {
default:
break;
diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index 1c7bb36f0d34c0..6d881be56dc2b4 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -815,6 +815,23 @@ define i1 @test46(i32 %X, i32 %Y, i32 %Z) {
ret i1 %C
}
+define i1 @test46_multiuse(i32 %X, i32 %Y, i32 %Z) {
+; CHECK-LABEL: @test46_multiuse(
+; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT: call void @use_i32(i32 [[A]])
+; CHECK-NEXT: [[B:%.*]] = ashr exact i32 [[Y:%.*]], [[Z]]
+; CHECK-NEXT: call void @use_i32(i32 [[B]])
+; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X]], [[Y]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %A = ashr exact i32 %X, %Z
+ call void @use_i32(i32 %A)
+ %B = ashr exact i32 %Y, %Z
+ call void @use_i32(i32 %B)
+ %C = icmp ult i32 %A, %B
+ ret i1 %C
+}
+
; PR9343 #5
define i1 @test47(i32 %X, i32 %Y, i32 %Z) {
; CHECK-LABEL: @test47(
|
This patch breaks the alias analysis and causes some regressions. We should do the simplification when at least one binop is one-use. |
cfa9abb
to
aa88812
Compare
Done. All regressions have been fixed except for dtcxzyw/llvm-opt-benchmark#49 (comment). I will post a patch for clang later. |
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.
LGTM
…Z), (binop Y, Z)` (llvm#76384) This patch relaxes the one-use constraints for `icmp pred (binop X, Z), (binop Y, Z)`. It will enable more optimizations with pointer arithmetic. One example in `boost::match_results::set_size`: ``` declare void @use(i64) define i1 @src(ptr %a1, ptr %a2, ptr %add.ptr.i66, i64 %sub.ptr.rhs.cast.i) { %sub.ptr.lhs.cast.i = ptrtoint ptr %a1 to i64 %sub.ptr.rhs.cast.i = ptrtoint ptr %a2 to i64 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i %sub.ptr.div.i = sdiv exact i64 %sub.ptr.sub.i, 24 call void @use(i64 %sub.ptr.div.i) %sub.ptr.lhs.cast.i.i = ptrtoint ptr %add.ptr.i66 to i64 %sub.ptr.sub.i.i = sub i64 %sub.ptr.lhs.cast.i.i, %sub.ptr.rhs.cast.i %sub.ptr.div.i.i = sdiv exact i64 %sub.ptr.sub.i.i, 24 %cmp.i.not.i.i = icmp eq i64 %sub.ptr.div.i.i, %sub.ptr.div.i ret i1 %cmp.i.not.i.i } define i1 @tgt(ptr %a1, ptr %a2, ptr %add.ptr.i66, i64 %sub.ptr.rhs.cast.i) { %sub.ptr.lhs.cast.i = ptrtoint ptr %a1 to i64 %sub.ptr.rhs.cast.i = ptrtoint ptr %a2 to i64 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i %sub.ptr.div.i = sdiv exact i64 %sub.ptr.sub.i, 24 call void @use(i64 %sub.ptr.div.i) %cmp.i.not.i.i = icmp eq i64 %sub.ptr.sub.i.i, %sub.ptr.sub.i ret i1 %cmp.i.not.i.i } ```
This patch relaxes the one-use constraints for
icmp pred (binop X, Z), (binop Y, Z)
. It will enable more optimizations with pointer arithmetic.One example in
boost::match_results::set_size
: