[llvm] ecd2508 - [InstCombine] Add (icmp eq B, 0) | (icmp ult/gt A, B) -> (icmp ule A, B-1) vector support

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 19 07:25:27 PDT 2020


Author: Simon Pilgrim
Date: 2020-10-19T15:23:48+01:00
New Revision: ecd25086d142a0a07bb774c54ba51b042a47c31c

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

LOG: [InstCombine] Add (icmp eq B, 0) | (icmp ult/gt A, B) -> (icmp ule A, B-1) vector support

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/test/Transforms/InstCombine/icmp.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 1e9e54796dbd..9b3e373f6a0e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2351,14 +2351,11 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
   if (Value *V = foldLogOpOfMaskedICmps(LHS, RHS, false, Builder))
     return V;
 
-  auto *LHSC = dyn_cast<ConstantInt>(LHS1);
-  auto *RHSC = dyn_cast<ConstantInt>(RHS1);
-
   if (LHS->hasOneUse() || RHS->hasOneUse()) {
     // (icmp eq B, 0) | (icmp ult A, B) -> (icmp ule A, B-1)
     // (icmp eq B, 0) | (icmp ugt B, A) -> (icmp ule A, B-1)
     Value *A = nullptr, *B = nullptr;
-    if (PredL == ICmpInst::ICMP_EQ && LHSC && LHSC->isZero()) {
+    if (PredL == ICmpInst::ICMP_EQ && match(LHS1, m_Zero())) {
       B = LHS0;
       if (PredR == ICmpInst::ICMP_ULT && LHS0 == RHS1)
         A = RHS0;
@@ -2367,17 +2364,17 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
     }
     // (icmp ult A, B) | (icmp eq B, 0) -> (icmp ule A, B-1)
     // (icmp ugt B, A) | (icmp eq B, 0) -> (icmp ule A, B-1)
-    else if (PredR == ICmpInst::ICMP_EQ && RHSC && RHSC->isZero()) {
+    else if (PredR == ICmpInst::ICMP_EQ && match(RHS1, m_Zero())) {
       B = RHS0;
       if (PredL == ICmpInst::ICMP_ULT && RHS0 == LHS1)
         A = LHS0;
-      else if (PredL == ICmpInst::ICMP_UGT && LHS0 == RHS0)
+      else if (PredL == ICmpInst::ICMP_UGT && RHS0 == LHS0)
         A = LHS1;
     }
     if (A && B)
       return Builder.CreateICmp(
           ICmpInst::ICMP_UGE,
-          Builder.CreateAdd(B, ConstantInt::getSigned(B->getType(), -1)), A);
+          Builder.CreateAdd(B, ConstantInt::getAllOnesValue(B->getType())), A);
   }
 
   if (Value *V = foldAndOrOfICmpsWithConstEq(LHS, RHS, Or, Builder, Q))
@@ -2407,6 +2404,8 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
     return X;
 
   // This only handles icmp of constants: (icmp1 A, C1) | (icmp2 B, C2).
+  auto *LHSC = dyn_cast<ConstantInt>(LHS1);
+  auto *RHSC = dyn_cast<ConstantInt>(RHS1);
   if (!LHSC || !RHSC)
     return nullptr;
 

diff  --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index 6a3a9e97ce71..c6bfc29a15c1 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -2164,10 +2164,9 @@ define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) {
 
 define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_uniform(<2 x i64> %a, <2 x i64> %b) {
 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_uniform(
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i64> [[B:%.*]], zeroinitializer
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult <2 x i64> [[A:%.*]], [[B]]
-; CHECK-NEXT:    [[TMP3:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]]
-; CHECK-NEXT:    ret <2 x i1> [[TMP3]]
+; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], <i64 -1, i64 -1>
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]]
+; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
 ;
   %1 = icmp eq <2 x i64> %b, zeroinitializer
   %2 = icmp ult <2 x i64> %a, %b
@@ -2177,10 +2176,9 @@ define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_uniform(<2 x i64> %a, <2 x i64> %b)
 
 define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_undef(<2 x i64> %a, <2 x i64> %b) {
 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_undef(
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i64> [[B:%.*]], <i64 0, i64 undef>
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult <2 x i64> [[A:%.*]], [[B]]
-; CHECK-NEXT:    [[TMP3:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]]
-; CHECK-NEXT:    ret <2 x i1> [[TMP3]]
+; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], <i64 -1, i64 -1>
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]]
+; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
 ;
   %1 = icmp eq <2 x i64> %b, <i64 0, i64 undef>
   %2 = icmp ult <2 x i64> %a, %b


        


More information about the llvm-commits mailing list