[llvm] r268059 - [InstCombine] add helper function for ICmp with constant canonicalization; NFCI

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 29 09:22:25 PDT 2016


Author: spatel
Date: Fri Apr 29 11:22:25 2016
New Revision: 268059

URL: http://llvm.org/viewvc/llvm-project?rev=268059&view=rev
Log:
[InstCombine] add helper function for ICmp with constant canonicalization; NFCI

As suggested in http://reviews.llvm.org/D17859 , we should enhance this
to support vectors.


Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=268059&r1=268058&r2=268059&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Fri Apr 29 11:22:25 2016
@@ -3070,6 +3070,41 @@ bool InstCombiner::replacedSelectWithOpe
   return false;
 }
 
+/// If we have an icmp le or icmp ge instruction with a constant operand, turn
+/// it into the appropriate icmp lt or icmp gt instruction. This transform
+/// allows them to be folded in visitICmpInst.
+static ICmpInst *canonicalizeCmpWithConstant(ICmpInst &I,
+                                             InstCombiner::BuilderTy &Builder) {
+  Value *Op0 = I.getOperand(0);
+  Value *Op1 = I.getOperand(1);
+
+  if (auto *Op1C = dyn_cast<ConstantInt>(Op1)) {
+    // For scalars, SimplifyICmpInst has already handled the edge cases for us,
+    // so we just assert on them.
+    APInt Op1Val = Op1C->getValue();
+    switch (I.getPredicate()) {
+    case ICmpInst::ICMP_ULE:
+      assert(!Op1C->isMaxValue(false)); // A <=u MAX -> TRUE
+      return new ICmpInst(ICmpInst::ICMP_ULT, Op0, Builder.getInt(Op1Val + 1));
+    case ICmpInst::ICMP_SLE:
+      assert(!Op1C->isMaxValue(true));  // A <=s MAX -> TRUE
+      return new ICmpInst(ICmpInst::ICMP_SLT, Op0, Builder.getInt(Op1Val + 1));
+    case ICmpInst::ICMP_UGE:
+      assert(!Op1C->isMinValue(false)); // A >=u MIN -> TRUE
+      return new ICmpInst(ICmpInst::ICMP_UGT, Op0, Builder.getInt(Op1Val - 1));
+    case ICmpInst::ICMP_SGE:
+      assert(!Op1C->isMinValue(true));  // A >=s MIN -> TRUE
+      return new ICmpInst(ICmpInst::ICMP_SGT, Op0, Builder.getInt(Op1Val - 1));
+    default:
+      break;
+    }
+  }
+
+  // TODO: Handle vectors.
+
+  return nullptr;
+}
+
 Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
   bool Changed = false;
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
@@ -3153,6 +3188,9 @@ Instruction *InstCombiner::visitICmpInst
     }
   }
 
+  if (ICmpInst *NewICmp = canonicalizeCmpWithConstant(I, *Builder))
+    return NewICmp;
+
   unsigned BitWidth = 0;
   if (Ty->isIntOrIntVectorTy())
     BitWidth = Ty->getScalarSizeInBits();
@@ -3227,30 +3265,6 @@ Instruction *InstCombiner::visitICmpInst
         return new ICmpInst(ICmpInst::ICMP_SLE, A, B);
     }
 
-    // If we have an icmp le or icmp ge instruction, turn it into the
-    // appropriate icmp lt or icmp gt instruction.  This allows us to rely on
-    // them being folded in the code below.  The SimplifyICmpInst code has
-    // already handled the edge cases for us, so we just assert on them.
-    switch (I.getPredicate()) {
-    default: break;
-    case ICmpInst::ICMP_ULE:
-      assert(!CI->isMaxValue(false));                 // A <=u MAX -> TRUE
-      return new ICmpInst(ICmpInst::ICMP_ULT, Op0,
-                          Builder->getInt(CI->getValue()+1));
-    case ICmpInst::ICMP_SLE:
-      assert(!CI->isMaxValue(true));                  // A <=s MAX -> TRUE
-      return new ICmpInst(ICmpInst::ICMP_SLT, Op0,
-                          Builder->getInt(CI->getValue()+1));
-    case ICmpInst::ICMP_UGE:
-      assert(!CI->isMinValue(false));                 // A >=u MIN -> TRUE
-      return new ICmpInst(ICmpInst::ICMP_UGT, Op0,
-                          Builder->getInt(CI->getValue()-1));
-    case ICmpInst::ICMP_SGE:
-      assert(!CI->isMinValue(true));                  // A >=s MIN -> TRUE
-      return new ICmpInst(ICmpInst::ICMP_SGT, Op0,
-                          Builder->getInt(CI->getValue()-1));
-    }
-
     if (I.isEquality()) {
       ConstantInt *CI2;
       if (match(Op0, m_AShr(m_ConstantInt(CI2), m_Value(A))) ||




More information about the llvm-commits mailing list