InstCombine: merge constants in both operands of icmp.
[oota-llvm.git] / lib / Transforms / InstCombine / InstCombineCompares.cpp
index 8c0ad525980a801292d5ab4139eb3d313ce9c66c..9bf3818954204713cd9794378de5a74c4b499a00 100644 (file)
@@ -3008,6 +3008,19 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
     // icmp X, X+Cst
     if (match(Op1, m_Add(m_Value(X), m_ConstantInt(Cst))) && Op0 == X)
       return FoldICmpAddOpCst(I, X, Cst, I.getSwappedPredicate());
+
+    ConstantInt *Cst2;
+    if (match(Op1, m_ConstantInt(Cst)) &&
+        match(Op0, m_Add(m_Value(X), m_ConstantInt(Cst2))) &&
+        cast<BinaryOperator>(Op0)->hasNoSignedWrap()) {
+      // icmp X+Cst2, Cst --> icmp X, Cst-Cst2
+      // iff Cst-Cst2 does not overflow
+      bool Overflow;
+      APInt NewCst = Cst->getValue().ssub_ov(Cst2->getValue(), Overflow);
+      if (!Overflow)
+        return new ICmpInst(I.getPredicate(), X,
+                            ConstantInt::get(Cst->getType(), NewCst));
+    }
   }
   return Changed ? &I : 0;
 }