[llvm] r278935 - [InstCombine] use m_APInt to allow icmp (add X, Y), C folds for splat constant vectors

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 17 08:24:31 PDT 2016


Author: spatel
Date: Wed Aug 17 10:24:30 2016
New Revision: 278935

URL: http://llvm.org/viewvc/llvm-project?rev=278935&view=rev
Log:
[InstCombine] use m_APInt to allow icmp (add X, Y), C folds for splat constant vectors

This is a sibling of:
https://reviews.llvm.org/rL278859


Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/trunk/test/Transforms/InstCombine/2008-01-29-AddICmp.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=278935&r1=278934&r2=278935&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Wed Aug 17 10:24:30 2016
@@ -2198,53 +2198,48 @@ Instruction *InstCombiner::foldICmpSubCo
 /// Fold icmp (add X, Y), C.
 Instruction *InstCombiner::foldICmpAddConstant(ICmpInst &Cmp, Instruction *Add,
                                                const APInt *C) {
-  // FIXME: This check restricts all folds under here to scalar types.
-  ConstantInt *RHS = dyn_cast<ConstantInt>(Cmp.getOperand(1));
-  if (!RHS)
+  Value *Y = Add->getOperand(1);
+  const APInt *C2;
+  if (Cmp.isEquality() || !match(Y, m_APInt(C2)))
     return nullptr;
 
-  if (Cmp.isEquality())
-    return nullptr;
-
-  // Fold: icmp pred (add X, C2), C
+  // Fold icmp pred (add X, C2), C.
   Value *X = Add->getOperand(0);
-  ConstantInt *AddC = dyn_cast<ConstantInt>(Add->getOperand(1));
-  if (!AddC)
-    return nullptr;
-
-  const APInt &C2 = AddC->getValue();
-  ConstantRange CR = Cmp.makeConstantRange(Cmp.getPredicate(), *C).subtract(C2);
+  Type *Ty = Add->getType();
+  auto CR = Cmp.makeConstantRange(Cmp.getPredicate(), *C).subtract(*C2);
   const APInt &Upper = CR.getUpper();
   const APInt &Lower = CR.getLower();
   if (Cmp.isSigned()) {
     if (Lower.isSignBit())
-      return new ICmpInst(ICmpInst::ICMP_SLT, X, Builder->getInt(Upper));
+      return new ICmpInst(ICmpInst::ICMP_SLT, X, ConstantInt::get(Ty, Upper));
     if (Upper.isSignBit())
-      return new ICmpInst(ICmpInst::ICMP_SGE, X, Builder->getInt(Lower));
+      return new ICmpInst(ICmpInst::ICMP_SGE, X, ConstantInt::get(Ty, Lower));
   } else {
     if (Lower.isMinValue())
-      return new ICmpInst(ICmpInst::ICMP_ULT, X, Builder->getInt(Upper));
+      return new ICmpInst(ICmpInst::ICMP_ULT, X, ConstantInt::get(Ty, Upper));
     if (Upper.isMinValue())
-      return new ICmpInst(ICmpInst::ICMP_UGE, X, Builder->getInt(Lower));
+      return new ICmpInst(ICmpInst::ICMP_UGE, X, ConstantInt::get(Ty, Lower));
   }
 
-  if (Add->hasOneUse()) {
-    // X+C <u C2 -> (X & -C2) == C
-    //   iff C & (C2-1) == 0
-    //       C2 is a power of 2
-    if (Cmp.getPredicate() == ICmpInst::ICMP_ULT && C->isPowerOf2() &&
-        (C2 & (*C - 1)) == 0)
-      return new ICmpInst(ICmpInst::ICMP_EQ, Builder->CreateAnd(X, -(*C)),
-                          ConstantExpr::getNeg(AddC));
-
-    // X+C >u C2 -> (X & ~C2) != C
-    //   iff C & C2 == 0
-    //       C2+1 is a power of 2
-    if (Cmp.getPredicate() == ICmpInst::ICMP_UGT && (*C + 1).isPowerOf2() &&
-        (C2 & *C) == 0)
-      return new ICmpInst(ICmpInst::ICMP_NE, Builder->CreateAnd(X, ~(*C)),
-                          ConstantExpr::getNeg(AddC));
-  }
+  if (!Add->hasOneUse())
+    return nullptr;
+
+  // X+C <u C2 -> (X & -C2) == C
+  //   iff C & (C2-1) == 0
+  //       C2 is a power of 2
+  if (Cmp.getPredicate() == ICmpInst::ICMP_ULT && C->isPowerOf2() &&
+      (*C2 & (*C - 1)) == 0)
+    return new ICmpInst(ICmpInst::ICMP_EQ, Builder->CreateAnd(X, -(*C)),
+                        ConstantExpr::getNeg(cast<Constant>(Y)));
+
+  // X+C >u C2 -> (X & ~C2) != C
+  //   iff C & C2 == 0
+  //       C2+1 is a power of 2
+  if (Cmp.getPredicate() == ICmpInst::ICMP_UGT && (*C + 1).isPowerOf2() &&
+      (*C2 & *C) == 0)
+    return new ICmpInst(ICmpInst::ICMP_NE, Builder->CreateAnd(X, ~(*C)),
+                        ConstantExpr::getNeg(cast<Constant>(Y)));
+
   return nullptr;
 }
 

Modified: llvm/trunk/test/Transforms/InstCombine/2008-01-29-AddICmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2008-01-29-AddICmp.ll?rev=278935&r1=278934&r2=278935&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/2008-01-29-AddICmp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/2008-01-29-AddICmp.ll Wed Aug 17 10:24:30 2016
@@ -2,7 +2,6 @@
 ; RUN: opt < %s -instcombine -S | FileCheck %s
 
 ; PR1949
-; FIXME: Vectors should fold the same way for all tests.
 
 define i1 @test1(i32 %a) {
 ; CHECK-LABEL: @test1(
@@ -16,8 +15,7 @@ define i1 @test1(i32 %a) {
 
 define <2 x i1> @test1vec(<2 x i32> %a) {
 ; CHECK-LABEL: @test1vec(
-; CHECK-NEXT:    [[B:%.*]] = add <2 x i32> %a, <i32 4, i32 4>
-; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i32> [[B]], <i32 4, i32 4>
+; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i32> %a, <i32 -5, i32 -5>
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
   %b = add <2 x i32> %a, <i32 4, i32 4>
@@ -37,8 +35,7 @@ define i1 @test2(i32 %a) {
 
 define <2 x i1> @test2vec(<2 x i32> %a) {
 ; CHECK-LABEL: @test2vec(
-; CHECK-NEXT:    [[B:%.*]] = add <2 x i32> %a, <i32 -4, i32 -4>
-; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i32> [[B]], <i32 -5, i32 -5>
+; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i32> %a, <i32 4, i32 4>
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
   %b = sub <2 x i32> %a, <i32 4, i32 4>
@@ -58,8 +55,7 @@ define i1 @test3(i32 %a) {
 
 define <2 x i1> @test3vec(<2 x i32> %a) {
 ; CHECK-LABEL: @test3vec(
-; CHECK-NEXT:    [[B:%.*]] = add <2 x i32> %a, <i32 4, i32 4>
-; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i32> [[B]], <i32 -2147483644, i32 -2147483644>
+; CHECK-NEXT:    [[C:%.*]] = icmp sgt <2 x i32> %a, <i32 2147483643, i32 2147483643>
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
   %b = add <2 x i32> %a, <i32 4, i32 4>
@@ -79,8 +75,7 @@ define i1 @test4(i32 %a) {
 
 define <2 x i1> @test4vec(<2 x i32> %a) {
 ; CHECK-LABEL: @test4vec(
-; CHECK-NEXT:    [[B:%.*]] = add <2 x i32> %a, <i32 -2147483644, i32 -2147483644>
-; CHECK-NEXT:    [[C:%.*]] = icmp sgt <2 x i32> [[B]], <i32 3, i32 3>
+; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i32> %a, <i32 -4, i32 -4>
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
   %b = add <2 x i32> %a, <i32 2147483652, i32 2147483652>

Modified: llvm/trunk/test/Transforms/InstCombine/icmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/icmp.ll?rev=278935&r1=278934&r2=278935&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/icmp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/icmp.ll Wed Aug 17 10:24:30 2016
@@ -1727,11 +1727,10 @@ define i1 @icmp_add_ult_2(i32 %X) {
   ret i1 %cmp
 }
 
-; FIXME: Vectors should fold too.
 define <2 x i1> @icmp_add_X_-14_ult_2_vec(<2 x i32> %X) {
 ; CHECK-LABEL: @icmp_add_X_-14_ult_2_vec(
-; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i32> %X, <i32 -14, i32 -14>
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[ADD]], <i32 2, i32 2>
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> %X, <i32 -2, i32 -2>
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 14, i32 14>
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %add = add <2 x i32> %X, <i32 -14, i32 -14>
@@ -1772,11 +1771,10 @@ define i1 @icmp_add_X_-14_uge_2(i32 %X)
   ret i1 %cmp
 }
 
-; FIXME: Vectors should fold too.
 define <2 x i1> @icmp_add_X_-14_uge_2_vec(<2 x i32> %X) {
 ; CHECK-LABEL: @icmp_add_X_-14_uge_2_vec(
-; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i32> %X, <i32 -14, i32 -14>
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[ADD]], <i32 1, i32 1>
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> %X, <i32 -2, i32 -2>
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 14, i32 14>
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %add = add <2 x i32> %X, <i32 -14, i32 -14>




More information about the llvm-commits mailing list