[llvm] 32679e1 - [InstCombine] Handle logical op for and/or of icmp 0/-1

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 22 07:19:04 PDT 2024


Author: Nikita Popov
Date: 2024-08-22T16:17:39+02:00
New Revision: 32679e10a9b66405c340213993f65b2edf5a794a

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

LOG: [InstCombine] Handle logical op for and/or of icmp 0/-1

This aligns the transform with what foldLogOpOfMaskedICmp() does.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/test/Transforms/InstCombine/bit-checks.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 2bba83b5cde3c7..b703bc7d04db58 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -3384,9 +3384,10 @@ Value *InstCombinerImpl::foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
   // (icmp ne A, 0) | (icmp ne B, 0) --> (icmp ne (A|B), 0)
   // (icmp eq A, 0) & (icmp eq B, 0) --> (icmp eq (A|B), 0)
   // TODO: Remove this and below when foldLogOpOfMaskedICmps can handle undefs.
-  if (!IsLogical && PredL == (IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE) &&
+  if (PredL == (IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE) &&
       PredL == PredR && match(LHS1, m_ZeroInt()) && match(RHS1, m_ZeroInt()) &&
-      LHS0->getType() == RHS0->getType()) {
+      LHS0->getType() == RHS0->getType() &&
+      (!IsLogical || isGuaranteedNotToBePoison(RHS0))) {
     Value *NewOr = Builder.CreateOr(LHS0, RHS0);
     return Builder.CreateICmp(PredL, NewOr,
                               Constant::getNullValue(NewOr->getType()));
@@ -3394,9 +3395,10 @@ Value *InstCombinerImpl::foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
 
   // (icmp ne A, -1) | (icmp ne B, -1) --> (icmp ne (A&B), -1)
   // (icmp eq A, -1) & (icmp eq B, -1) --> (icmp eq (A&B), -1)
-  if (!IsLogical && PredL == (IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE) &&
+  if (PredL == (IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE) &&
       PredL == PredR && match(LHS1, m_AllOnes()) && match(RHS1, m_AllOnes()) &&
-      LHS0->getType() == RHS0->getType()) {
+      LHS0->getType() == RHS0->getType() &&
+      (!IsLogical || isGuaranteedNotToBePoison(RHS0))) {
     Value *NewAnd = Builder.CreateAnd(LHS0, RHS0);
     return Builder.CreateICmp(PredL, NewAnd,
                               Constant::getAllOnesValue(LHS0->getType()));

diff  --git a/llvm/test/Transforms/InstCombine/bit-checks.ll b/llvm/test/Transforms/InstCombine/bit-checks.ll
index 93cf09f530192f..d1b61040853705 100644
--- a/llvm/test/Transforms/InstCombine/bit-checks.ll
+++ b/llvm/test/Transforms/InstCombine/bit-checks.ll
@@ -1357,11 +1357,10 @@ define i1 @no_masks_with_logical_or2(i32 %a, i32 %b, i32 noundef %c) {
 
 define <2 x i1> @no_masks_with_logical_or_vec_poison1(<2 x i32> %a, <2 x i32> %b, <2 x i32> noundef %c) {
 ; CHECK-LABEL: @no_masks_with_logical_or_vec_poison1(
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne <2 x i32> [[A:%.*]], <i32 0, i32 poison>
 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne <2 x i32> [[B:%.*]], <i32 63, i32 poison>
-; CHECK-NEXT:    [[OR1:%.*]] = select <2 x i1> [[CMP1]], <2 x i1> <i1 true, i1 true>, <2 x i1> [[CMP2]]
-; CHECK-NEXT:    [[CMP3:%.*]] = icmp ne <2 x i32> [[C:%.*]], <i32 0, i32 poison>
-; CHECK-NEXT:    [[OR2:%.*]] = or <2 x i1> [[OR1]], [[CMP3]]
+; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
+; CHECK-NEXT:    [[OR2:%.*]] = select <2 x i1> [[TMP2]], <2 x i1> <i1 true, i1 true>, <2 x i1> [[CMP2]]
 ; CHECK-NEXT:    ret <2 x i1> [[OR2]]
 ;
   %cmp1 = icmp ne <2 x i32> %a, <i32 0, i32 poison>
@@ -1374,11 +1373,10 @@ define <2 x i1> @no_masks_with_logical_or_vec_poison1(<2 x i32> %a, <2 x i32> %b
 
 define <2 x i1> @no_masks_with_logical_or_vec_poison2(<2 x i32> %a, <2 x i32> %b, <2 x i32> noundef %c) {
 ; CHECK-LABEL: @no_masks_with_logical_or_vec_poison2(
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne <2 x i32> [[A:%.*]], <i32 -1, i32 poison>
 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne <2 x i32> [[B:%.*]], <i32 63, i32 poison>
-; CHECK-NEXT:    [[OR1:%.*]] = select <2 x i1> [[CMP1]], <2 x i1> <i1 true, i1 true>, <2 x i1> [[CMP2]]
-; CHECK-NEXT:    [[CMP3:%.*]] = icmp ne <2 x i32> [[C:%.*]], <i32 -1, i32 poison>
-; CHECK-NEXT:    [[OR2:%.*]] = or <2 x i1> [[OR1]], [[CMP3]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 -1, i32 -1>
+; CHECK-NEXT:    [[OR2:%.*]] = select <2 x i1> [[TMP2]], <2 x i1> <i1 true, i1 true>, <2 x i1> [[CMP2]]
 ; CHECK-NEXT:    ret <2 x i1> [[OR2]]
 ;
   %cmp1 = icmp ne <2 x i32> %a, <i32 -1, i32 poison>


        


More information about the llvm-commits mailing list