[llvm] r281663 - [InstCombine] allow icmp (shr/shl) folds for vectors

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 15 14:35:31 PDT 2016


Author: spatel
Date: Thu Sep 15 16:35:30 2016
New Revision: 281663

URL: http://llvm.org/viewvc/llvm-project?rev=281663&view=rev
Log:
[InstCombine] allow icmp (shr/shl) folds for vectors

These 2 helper functions were already using APInt internally, so just
change the API and caller to allow folds for splats. The scalar
regression tests look quite thorough, so I just added a couple of
tests to prove that vectors are handled too.

These folds should be grouped with the other cmp+shift folds though.
That can be an NFC follow-up.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h
    llvm/trunk/test/Transforms/InstCombine/icmp-shr.ll
    llvm/trunk/test/Transforms/InstCombine/icmp.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=281663&r1=281662&r2=281663&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Thu Sep 15 16:35:30 2016
@@ -1177,8 +1177,8 @@ Instruction *InstCombiner::foldICmpAddOp
 /// (icmp eq/ne A, Log2(const2/const1)) ->
 /// (icmp eq/ne A, Log2(const2) - Log2(const1)).
 Instruction *InstCombiner::foldICmpCstShrConst(ICmpInst &I, Value *Op, Value *A,
-                                             ConstantInt *CI1,
-                                             ConstantInt *CI2) {
+                                               const APInt &AP1,
+                                               const APInt &AP2) {
   assert(I.isEquality() && "Cannot fold icmp gt/lt");
 
   auto getICmp = [&I](CmpInst::Predicate Pred, Value *LHS, Value *RHS) {
@@ -1187,9 +1187,6 @@ Instruction *InstCombiner::foldICmpCstSh
     return new ICmpInst(Pred, LHS, RHS);
   };
 
-  const APInt &AP1 = CI1->getValue();
-  const APInt &AP2 = CI2->getValue();
-
   // Don't bother doing any work for cases which InstSimplify handles.
   if (AP2 == 0)
     return nullptr;
@@ -1238,8 +1235,8 @@ Instruction *InstCombiner::foldICmpCstSh
 /// Handle "(icmp eq/ne (shl const2, A), const1)" ->
 /// (icmp eq/ne A, TrailingZeros(const1) - TrailingZeros(const2)).
 Instruction *InstCombiner::foldICmpCstShlConst(ICmpInst &I, Value *Op, Value *A,
-                                               ConstantInt *CI1,
-                                               ConstantInt *CI2) {
+                                               const APInt &AP1,
+                                               const APInt &AP2) {
   assert(I.isEquality() && "Cannot fold icmp gt/lt");
 
   auto getICmp = [&I](CmpInst::Predicate Pred, Value *LHS, Value *RHS) {
@@ -1248,9 +1245,6 @@ Instruction *InstCombiner::foldICmpCstSh
     return new ICmpInst(Pred, LHS, RHS);
   };
 
-  const APInt &AP1 = CI1->getValue();
-  const APInt &AP2 = CI2->getValue();
-
   // Don't bother doing any work for cases which InstSimplify handles.
   if (AP2 == 0)
     return nullptr;
@@ -1258,8 +1252,9 @@ Instruction *InstCombiner::foldICmpCstSh
   unsigned AP2TrailingZeros = AP2.countTrailingZeros();
 
   if (!AP1 && AP2TrailingZeros != 0)
-    return getICmp(I.ICMP_UGE, A,
-                   ConstantInt::get(A->getType(), AP2.getBitWidth() - AP2TrailingZeros));
+    return getICmp(
+        I.ICMP_UGE, A,
+        ConstantInt::get(A->getType(), AP2.getBitWidth() - AP2TrailingZeros));
 
   if (AP1 == AP2)
     return getICmp(I.ICMP_EQ, A, ConstantInt::getNullValue(A->getType()));
@@ -1408,26 +1403,26 @@ Instruction *InstCombiner::foldICmpWithC
     }
   }
 
-  // FIXME: Use m_APInt to allow folds for splat constants.
-  ConstantInt *CI = dyn_cast<ConstantInt>(Cmp.getOperand(1));
-  if (!CI)
-    return nullptr;
-
   if (Cmp.isEquality()) {
-    ConstantInt *CI2;
-    if (match(X, m_AShr(m_ConstantInt(CI2), m_Value(A))) ||
-        match(X, m_LShr(m_ConstantInt(CI2), m_Value(A)))) {
+    const APInt *C2;
+    if (match(X, m_AShr(m_APInt(C2), m_Value(A))) ||
+        match(X, m_LShr(m_APInt(C2), m_Value(A)))) {
       // (icmp eq/ne (ashr/lshr const2, A), const1)
-      if (Instruction *Inst = foldICmpCstShrConst(Cmp, X, A, CI, CI2))
+      if (Instruction *Inst = foldICmpCstShrConst(Cmp, X, A, *C, *C2))
         return Inst;
     }
-    if (match(X, m_Shl(m_ConstantInt(CI2), m_Value(A)))) {
+    if (match(X, m_Shl(m_APInt(C2), m_Value(A)))) {
       // (icmp eq/ne (shl const2, A), const1)
-      if (Instruction *Inst = foldICmpCstShlConst(Cmp, X, A, CI, CI2))
+      if (Instruction *Inst = foldICmpCstShlConst(Cmp, X, A, *C, *C2))
         return Inst;
     }
   }
 
+  // FIXME: Use m_APInt to allow folds for splat constants.
+  ConstantInt *CI = dyn_cast<ConstantInt>(Cmp.getOperand(1));
+  if (!CI)
+    return nullptr;
+
   // Canonicalize icmp instructions based on dominating conditions.
   BasicBlock *Parent = Cmp.getParent();
   BasicBlock *Dom = Parent->getSinglePredecessor();

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h?rev=281663&r1=281662&r2=281663&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h Thu Sep 15 16:35:30 2016
@@ -549,9 +549,9 @@ private:
   Instruction *foldFCmpIntToFPConst(FCmpInst &I, Instruction *LHSI,
                                     Constant *RHSC);
   Instruction *foldICmpCstShrConst(ICmpInst &I, Value *Op, Value *A,
-                                   ConstantInt *CI1, ConstantInt *CI2);
+                                   const APInt &C1, const APInt &C2);
   Instruction *foldICmpCstShlConst(ICmpInst &I, Value *Op, Value *A,
-                                   ConstantInt *CI1, ConstantInt *CI2);
+                                   const APInt &C1, const APInt &C2);
   Instruction *foldICmpAddOpConst(Instruction &ICI, Value *X, ConstantInt *CI,
                                   ICmpInst::Predicate Pred);
   Instruction *foldICmpWithCastAndCast(ICmpInst &ICI);

Modified: llvm/trunk/test/Transforms/InstCombine/icmp-shr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/icmp-shr.ll?rev=281663&r1=281662&r2=281663&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/icmp-shr.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/icmp-shr.ll Thu Sep 15 16:35:30 2016
@@ -13,6 +13,16 @@ define i1 @lshr_eq_msb_low_last_zero(i8
   ret i1 %cmp
 }
 
+define <2 x i1> @lshr_eq_msb_low_last_zero_vec(<2 x i8> %a) {
+; CHECK-LABEL: @lshr_eq_msb_low_last_zero_vec(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i8> %a, <i8 6, i8 6>
+; CHECK-NEXT:    ret <2 x i1> [[CMP]]
+;
+  %shr = lshr <2 x i8> <i8 127, i8 127>, %a
+  %cmp = icmp eq <2 x i8> %shr, zeroinitializer
+  ret <2 x i1> %cmp
+}
+
 define i1 @ashr_eq_msb_low_second_zero(i8 %a) {
 ; CHECK-LABEL: @ashr_eq_msb_low_second_zero(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 %a, 6

Modified: llvm/trunk/test/Transforms/InstCombine/icmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/icmp.ll?rev=281663&r1=281662&r2=281663&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/icmp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/icmp.ll Thu Sep 15 16:35:30 2016
@@ -2194,6 +2194,16 @@ define i1 @shl_ap1_zero_ap2_non_zero_2(i
   ret i1 %cmp
 }
 
+define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec(<2 x i32> %a) {
+; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> %a, <i32 29, i32 29>
+; CHECK-NEXT:    ret <2 x i1> [[CMP]]
+;
+  %shl = shl <2 x i32> <i32 4, i32 4>, %a
+  %cmp = icmp eq <2 x i32> %shl, zeroinitializer
+  ret <2 x i1> %cmp
+}
+
 define i1 @shl_ap1_zero_ap2_non_zero_4(i32 %a) {
 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_4(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 %a, 30




More information about the llvm-commits mailing list