[llvm] [InstSimplify] Fold `and A, (zext (icmp eq A, 0))` into 0 (PR #66676)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 18 10:39:15 PDT 2023


https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/66676

This patch folds the pattern `and A, (zext (icmp eq A, 0))` into 0.
Fixes #66606.


>From 8773cab24d5c58ff70fa379450793498feb1e089 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 19 Sep 2023 01:15:01 +0800
Subject: [PATCH] [InstSimplify] Fold `and A, (zext (icmp eq A, 0))` into 0

---
 llvm/lib/Analysis/InstructionSimplify.cpp             |  7 +++++++
 llvm/test/Transforms/InstSimplify/and-or-icmp-zero.ll | 10 ++--------
 2 files changed, 9 insertions(+), 8 deletions(-)

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



More information about the llvm-commits mailing list