[llvm] 46aba71 - [InstCombine] (icmp eq A, -1) & (icmp eq B, -1) --> (icmp eq (A&B), -1)

Shivam Gupta via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 7 20:37:18 PDT 2023


Author: Shivam Gupta
Date: 2023-06-08T09:00:05+05:30
New Revision: 46aba711ab8311b427cac8ad8235642d86c7f7d6

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

LOG: [InstCombine] (icmp eq A, -1) & (icmp eq B, -1) --> (icmp eq (A&B), -1)

This patch add another icmp fold for -1 case.

This fixes https://github.com/llvm/llvm-project/issues/62311,
where we want instcombine to merge all compare intructions together so
later passes like simplifycfg and slpvectorize can better optimize this
chained comparison.

Reviewed By: goldstein.w.n

Differential Revision: https://reviews.llvm.org/D151660

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/test/Transforms/InstCombine/and-or-icmps.ll
    llvm/test/Transforms/PhaseOrdering/pr62311.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 10d84c61bf6a5..d9fab3f2a6b5a 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2938,7 +2938,7 @@ 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 when foldLogOpOfMaskedICmps can handle undefs.
+  // TODO: Remove this and below when foldLogOpOfMaskedICmps can handle undefs.
   if (!IsLogical && PredL == (IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE) &&
       PredL == PredR && match(LHS1, m_ZeroInt()) && match(RHS1, m_ZeroInt()) &&
       LHS0->getType() == RHS0->getType()) {
@@ -2947,6 +2947,16 @@ Value *InstCombinerImpl::foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
                               Constant::getNullValue(NewOr->getType()));
   }
 
+  // (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) &&
+      PredL == PredR && match(LHS1, m_AllOnes()) && match(RHS1, m_AllOnes()) &&
+      LHS0->getType() == RHS0->getType()) {
+    Value *NewAnd = Builder.CreateAnd(LHS0, RHS0);
+    return Builder.CreateICmp(PredL, NewAnd,
+                              Constant::getAllOnesValue(LHS0->getType()));
+  }
+
   // This only handles icmp of constants: (icmp1 A, C1) | (icmp2 B, C2).
   if (!LHSC || !RHSC)
     return nullptr;

diff  --git a/llvm/test/Transforms/InstCombine/and-or-icmps.ll b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
index 2cf2370dc9ca5..d7dedf8daa587 100644
--- a/llvm/test/Transforms/InstCombine/and-or-icmps.ll
+++ b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
@@ -2497,9 +2497,8 @@ define i1 @samesign_inverted_wrong_cmp(i32 %x, i32 %y) {
 
 define <2 x i1> @icmp_eq_m1_and_eq_m1(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: @icmp_eq_m1_and_eq_m1(
-; CHECK-NEXT:    [[RX:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 -1, i8 undef>
-; CHECK-NEXT:    [[RY:%.*]] = icmp eq <2 x i8> [[Y:%.*]], <i8 -1, i8 undef>
-; CHECK-NEXT:    [[R:%.*]] = and <2 x i1> [[RX]], [[RY]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[TMP1]], <i8 -1, i8 -1>
 ; CHECK-NEXT:    ret <2 x i1> [[R]]
 ;
   %rx = icmp eq <2 x i8> %x, <i8 -1, i8 undef>
@@ -2510,9 +2509,8 @@ define <2 x i1> @icmp_eq_m1_and_eq_m1(<2 x i8> %x, <2 x i8> %y) {
 
 define <2 x i1> @icmp_eq_m1_and_eq_undef_m1(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: @icmp_eq_m1_and_eq_undef_m1(
-; CHECK-NEXT:    [[RX:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 -1, i8 undef>
-; CHECK-NEXT:    [[RY:%.*]] = icmp eq <2 x i8> [[Y:%.*]], <i8 undef, i8 -1>
-; CHECK-NEXT:    [[R:%.*]] = and <2 x i1> [[RX]], [[RY]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[TMP1]], <i8 -1, i8 -1>
 ; CHECK-NEXT:    ret <2 x i1> [[R]]
 ;
   %rx = icmp eq <2 x i8> %x, <i8 -1, i8 undef>
@@ -2561,9 +2559,8 @@ define <2 x i1> @icmp_eq_m1_or_eq_m1_fail(<2 x i8> %x, <2 x i8> %y) {
 
 define <2 x i1> @icmp_ne_m1_or_ne_m1(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: @icmp_ne_m1_or_ne_m1(
-; CHECK-NEXT:    [[RX:%.*]] = icmp ne <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
-; CHECK-NEXT:    [[RY:%.*]] = icmp ne <2 x i8> [[Y:%.*]], <i8 -1, i8 undef>
-; CHECK-NEXT:    [[R:%.*]] = or <2 x i1> [[RX]], [[RY]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i8> [[TMP1]], <i8 -1, i8 -1>
 ; CHECK-NEXT:    ret <2 x i1> [[R]]
 ;
   %rx = icmp ne <2 x i8> %x, <i8 -1, i8 -1>

diff  --git a/llvm/test/Transforms/PhaseOrdering/pr62311.ll b/llvm/test/Transforms/PhaseOrdering/pr62311.ll
index 01d6383c9f82a..03276d83d8a01 100644
--- a/llvm/test/Transforms/PhaseOrdering/pr62311.ll
+++ b/llvm/test/Transforms/PhaseOrdering/pr62311.ll
@@ -19,31 +19,9 @@ target triple = "x86_64-unknown-linux-gnu"
 define noundef zeroext i1 @allones(<8 x i64> noundef %x) {
 ; CHECK-LABEL: @allones(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[VECEXT:%.*]] = extractelement <8 x i64> [[X:%.*]], i64 0
-; CHECK-NEXT:    [[VECEXT1:%.*]] = extractelement <8 x i64> [[X]], i64 1
-; CHECK-NEXT:    [[TMP0:%.*]] = and i64 [[VECEXT]], [[VECEXT1]]
-; CHECK-NEXT:    [[OR_COND:%.*]] = icmp eq i64 [[TMP0]], -1
-; CHECK-NEXT:    [[VECEXT4:%.*]] = extractelement <8 x i64> [[X]], i64 2
-; CHECK-NEXT:    [[VECEXT7:%.*]] = extractelement <8 x i64> [[X]], i64 3
-; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[VECEXT4]], [[VECEXT7]]
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[TMP1]], -1
-; CHECK-NEXT:    [[OR_COND21:%.*]] = and i1 [[OR_COND]], [[TMP2]]
-; CHECK-NEXT:    [[VECEXT10:%.*]] = extractelement <8 x i64> [[X]], i64 4
-; CHECK-NEXT:    [[VECEXT13:%.*]] = extractelement <8 x i64> [[X]], i64 5
-; CHECK-NEXT:    [[TMP3:%.*]] = and i64 [[VECEXT10]], [[VECEXT13]]
-; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq i64 [[TMP3]], -1
-; CHECK-NEXT:    [[OR_COND23:%.*]] = and i1 [[TMP4]], [[OR_COND21]]
-; CHECK-NEXT:    [[VECEXT16:%.*]] = extractelement <8 x i64> [[X]], i64 6
-; CHECK-NEXT:    [[CMP17:%.*]] = icmp eq i64 [[VECEXT16]], -1
-; CHECK-NEXT:    [[OR_COND24:%.*]] = and i1 [[CMP17]], [[OR_COND23]]
-; CHECK-NEXT:    br i1 [[OR_COND24]], label [[LAND_RHS:%.*]], label [[LAND_END:%.*]]
-; CHECK:       land.rhs:
-; CHECK-NEXT:    [[VECEXT18:%.*]] = extractelement <8 x i64> [[X]], i64 7
-; CHECK-NEXT:    [[CMP19:%.*]] = icmp eq i64 [[VECEXT18]], -1
-; CHECK-NEXT:    br label [[LAND_END]]
-; CHECK:       land.end:
-; CHECK-NEXT:    [[TMP5:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[CMP19]], [[LAND_RHS]] ]
-; CHECK-NEXT:    ret i1 [[TMP5]]
+; CHECK-NEXT:    [[TMP0:%.*]] = tail call i64 @llvm.vector.reduce.and.v8i64(<8 x i64> [[X:%.*]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], -1
+; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
 entry:
   %vecext = extractelement <8 x i64> %x, i32 0


        


More information about the llvm-commits mailing list