[llvm] f9478f7 - [InstSimplify] with logical ops: (X & Y) == -1 ? X : -1 --> -1

via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 26 00:57:33 PDT 2023


Author: Zhongyunde
Date: 2023-04-26T15:53:02+08:00
New Revision: f9478f729e68af4d32f20a93382f94744141d4a3

URL: https://github.com/llvm/llvm-project/commit/f9478f729e68af4d32f20a93382f94744141d4a3
DIFF: https://github.com/llvm/llvm-project/commit/f9478f729e68af4d32f20a93382f94744141d4a3.diff

LOG: [InstSimplify] with logical ops: (X & Y) == -1 ? X : -1 --> -1

Use simplifySelectWithICmpEq to handle the implied equalities from the icmp-and,
then both of ICMP_NE and ICMP_EQ will be addressed including vector type.
    (X & Y) == -1 ?  X : -1 --> -1 (commuted 2 ways)
    (X & Y) != -1 ? -1 :  X --> -1 (commuted 2 ways)
This is a supplement to the icmp-or scenario on D148986.

Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D149229

Added: 
    

Modified: 
    llvm/lib/Analysis/InstructionSimplify.cpp
    llvm/test/Transforms/InstSimplify/select_or_and.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 57cfef4e785c..d4639f6b8881 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4549,12 +4549,12 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
                                             Q, MaxRecurse))
       return V;
 
-    // select(X | Y == 0 ?  X : 0) --> 0 (commuted 2 ways)
     Value *X;
     Value *Y;
+    // select((X | Y) == 0 ?  X : 0) --> 0 (commuted 2 ways)
     if (match(CmpLHS, m_Or(m_Value(X), m_Value(Y))) &&
         match(CmpRHS, m_Zero())) {
-      // X | Y == 0 implies X == 0 and Y == 0.
+      // (X | Y) == 0 implies X == 0 and Y == 0.
       if (Value *V = simplifySelectWithICmpEq(X, CmpRHS, TrueVal, FalseVal, Q,
                                               MaxRecurse))
         return V;
@@ -4562,16 +4562,18 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
                                               MaxRecurse))
         return V;
     }
-  }
 
-  if (Pred == ICmpInst::Predicate::ICMP_EQ) {
-    Value *X;
-    Value *Y;
-    // select(X & Y == -1, X or Y, X & Y) -> X & Y
-    if (match(CondVal, m_ICmp(Pred, m_Specific(FalseVal), m_AllOnes())) &&
-        match(FalseVal, m_And(m_Value(X), m_Value(Y))) &&
-        (TrueVal == X || TrueVal == Y))
-      return FalseVal;
+    // select((X & Y) == -1 ?  X : -1) --> -1 (commuted 2 ways)
+    if (match(CmpLHS, m_And(m_Value(X), m_Value(Y))) &&
+        match(CmpRHS, m_AllOnes())) {
+      // (X & Y) == -1 implies X == -1 and Y == -1.
+      if (Value *V = simplifySelectWithICmpEq(X, CmpRHS, TrueVal, FalseVal, Q,
+                                              MaxRecurse))
+        return V;
+      if (Value *V = simplifySelectWithICmpEq(Y, CmpRHS, TrueVal, FalseVal, Q,
+                                              MaxRecurse))
+        return V;
+    }
   }
 
   return nullptr;

diff  --git a/llvm/test/Transforms/InstSimplify/select_or_and.ll b/llvm/test/Transforms/InstSimplify/select_or_and.ll
index 63ab7cd93613..6bb7fbf5dc41 100644
--- a/llvm/test/Transforms/InstSimplify/select_or_and.ll
+++ b/llvm/test/Transforms/InstSimplify/select_or_and.ll
@@ -147,10 +147,7 @@ define i32 @select_and_4(i32 %x, i32 %y) {
 ; select(Y & X != -1, Y, Y & X)
 define i32 @select_and_not_1(i32 %x, i32 %y) {
 ; CHECK-LABEL: @select_and_not_1(
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], -1
-; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[Y]]
-; CHECK-NEXT:    ret i32 [[RET]]
+; CHECK-NEXT:    ret i32 [[Y:%.*]]
 ;
   %and = and i32 %y, %x
   %cmp = icmp eq i32 %and, -1
@@ -161,10 +158,7 @@ define i32 @select_and_not_1(i32 %x, i32 %y) {
 ; select(Y & X != -1, Y, Y & X)
 define i32 @select_and_not_2(i32 %x, i32 %y) {
 ; CHECK-LABEL: @select_and_not_2(
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], -1
-; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND]]
-; CHECK-NEXT:    ret i32 [[RET]]
+; CHECK-NEXT:    ret i32 [[Y:%.*]]
 ;
   %and = and i32 %y, %x
   %cmp = icmp ne i32 %and, -1
@@ -186,13 +180,10 @@ define i32 @select_and_not_3(i32 %x, i32 %y) {
   ret i32 %ret
 }
 
-; TODO: https://alive2.llvm.org/ce/z/1ILbih
+; https://alive2.llvm.org/ce/z/1ILbih
 define i32 @select_icmp_and_eq(i32 %a, i32 %b) {
 ; CHECK-LABEL: @select_icmp_and_eq(
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[AND]], -1
-; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[A]], i32 -1
-; CHECK-NEXT:    ret i32 [[COND]]
+; CHECK-NEXT:    ret i32 -1
 ;
   %and = and i32 %a, %b
   %tobool = icmp eq i32 %and, -1
@@ -202,10 +193,7 @@ define i32 @select_icmp_and_eq(i32 %a, i32 %b) {
 
 define i32 @select_icmp_and_eq_commuted(i32 %a, i32 %b) {
 ; CHECK-LABEL: @select_icmp_and_eq_commuted(
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[AND]], -1
-; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[B]], i32 -1
-; CHECK-NEXT:    ret i32 [[COND]]
+; CHECK-NEXT:    ret i32 -1
 ;
   %and = and i32 %a, %b
   %tobool = icmp eq i32 %and, -1
@@ -216,10 +204,7 @@ define i32 @select_icmp_and_eq_commuted(i32 %a, i32 %b) {
 ; https://alive2.llvm.org/ce/z/HfYXvx
 define <2 x i16> @select_icmp_and_eq_vec(<2 x i16> %a, <2 x i16> %b) {
 ; CHECK-LABEL: @select_icmp_and_eq_vec(
-; CHECK-NEXT:    [[AND:%.*]] = and <2 x i16> [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq <2 x i16> [[AND]], <i16 -1, i16 -1>
-; CHECK-NEXT:    [[COND:%.*]] = select <2 x i1> [[TOBOOL]], <2 x i16> [[A]], <2 x i16> <i16 -1, i16 -1>
-; CHECK-NEXT:    ret <2 x i16> [[COND]]
+; CHECK-NEXT:    ret <2 x i16> <i16 -1, i16 -1>
 ;
   %and = and <2 x i16> %a, %b
   %tobool = icmp eq <2 x i16> %and, <i16 -1, i16 -1>
@@ -230,10 +215,7 @@ define <2 x i16> @select_icmp_and_eq_vec(<2 x i16> %a, <2 x i16> %b) {
 ; The ne should also be macthed
 define i32 @select_icmp_and_ne(i32 %a, i32 %b) {
 ; CHECK-LABEL: @select_icmp_and_ne(
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[AND]], -1
-; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 -1, i32 [[A]]
-; CHECK-NEXT:    ret i32 [[COND]]
+; CHECK-NEXT:    ret i32 -1
 ;
   %and = and i32 %a, %b
   %tobool = icmp ne i32 %and, -1


        


More information about the llvm-commits mailing list