-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[InstSimplify] Fold and A, (zext (icmp eq A, 0))
into 0
#66676
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 @llvm/pr-subscribers-llvm-analysis ChangesThis patch folds the pattern Full diff: https://github.com/llvm/llvm-project/pull/66676.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index e8f96e9f681f2d5..a835ca763e6565d 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2079,6 +2079,13 @@ static Value *simplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
if (match(Op0, m_Not(m_Specific(Op1))) || match(Op1, m_Not(m_Specific(Op0))))
return Constant::getNullValue(Op0->getType());
+ // A & !A = !A & A = 0
+ ICmpInst::Predicate EqPred;
+ if ((match(Op0, m_ZExt(m_ICmp(EqPred, m_Specific(Op1), m_Zero()))) ||
+ match(Op1, m_ZExt(m_ICmp(EqPred, m_Specific(Op0), m_Zero())))) &&
+ EqPred == ICmpInst::ICMP_EQ)
+ return Constant::getNullValue(Op0->getType());
+
// (A | ?) & A = A
if (match(Op0, m_c_Or(m_Specific(Op1), m_Value())))
return Op1;
diff --git a/llvm/test/Transforms/InstSimplify/and-or-icmp-zero.ll b/llvm/test/Transforms/InstSimplify/and-or-icmp-zero.ll
index 3e50a5968b46087..022add2c4717419 100644
--- a/llvm/test/Transforms/InstSimplify/and-or-icmp-zero.ll
+++ b/llvm/test/Transforms/InstSimplify/and-or-icmp-zero.ll
@@ -265,10 +265,7 @@ define i1 @and_cmps_ptr_eq_zero_with_mask_commute4(ptr %p, i64 %y) {
; tests from PR66606
define i32 @and_zext_eq_zero(i32 %a) {
; CHECK-LABEL: @and_zext_eq_zero(
-; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[A:%.*]], 0
-; CHECK-NEXT: [[NOT:%.*]] = zext i1 [[COND]] to i32
-; CHECK-NEXT: [[R:%.*]] = and i32 [[A]], [[NOT]]
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 0
;
%cond = icmp eq i32 %a, 0
%not = zext i1 %cond to i32
@@ -278,10 +275,7 @@ define i32 @and_zext_eq_zero(i32 %a) {
define i32 @and_zext_eq_zero_commuted(i32 %a) {
; CHECK-LABEL: @and_zext_eq_zero_commuted(
-; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[A:%.*]], 0
-; CHECK-NEXT: [[NOT:%.*]] = zext i1 [[COND]] to i32
-; CHECK-NEXT: [[R:%.*]] = and i32 [[NOT]], [[A]]
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 0
;
%cond = icmp eq i32 %a, 0
%not = zext i1 %cond to i32
|
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.
A bit niche, but LGTM.
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.
The general pattern here would be zext(c) & a
, which is c ? (a & 1) : 0
.
For the special case of c := a == C
, if C is even then this reduces to 0
, if C is odd it reduces to zext(c)
.
Possibly we shouldn't special case the a == C
case though and just generally canonicalize to the select form, on which all possible folds can then be performed?
In any case, this needs to at least handle arbitrary constants.
|
The canonicalization is posted as #66740. |
#66740) This patch canonicalizes the pattern `and(zext(A), B)` into `select A, B & 1, 0`. Thus, we can reuse transforms `select B == even, B & 1, 0 -> 0` and `select B == odd, B & 1, 0 -> zext(B == odd)` in `InstCombine`. It is an alternative to #66676. Alive2: https://alive2.llvm.org/ce/z/598phE Fixes #66733. Fixes #66606. Fixes #28612.
llvm#66740) This patch canonicalizes the pattern `and(zext(A), B)` into `select A, B & 1, 0`. Thus, we can reuse transforms `select B == even, B & 1, 0 -> 0` and `select B == odd, B & 1, 0 -> zext(B == odd)` in `InstCombine`. It is an alternative to llvm#66676. Alive2: https://alive2.llvm.org/ce/z/598phE Fixes llvm#66733. Fixes llvm#66606. Fixes llvm#28612.
This patch folds the pattern
and A, (zext (icmp eq A, 0))
into 0.Fixes #66606.