[llvm] [InstCombine] simplify `icmp pred x, ~x` (PR #73990)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 6 04:05:33 PST 2023


================
@@ -7035,6 +7035,51 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
       return new ICmpInst(I.getSwappedPredicate(Pred), Builder.CreateXor(X, Y),
                           Z);
 
+    // Transform X s<  ~X  -->   X s<  0
+    //           X s>  ~X  -->   X s>  -1
+    //           X s>= ~X  -->   X s>  -1
+    //           X s<= ~X  -->   X s<  0
+    //           X u<  ~X  -->   X s>  -1
+    //           X u>  ~X  -->   X s<  0
+    //           X u<= ~X  -->   X s>  -1
+    //           X u>= ~X  -->   X s<  0
+    //           X ==  ~X  -->   false
+    //           X !=  ~X  -->   true
+    if (match(&I, m_c_ICmp(Pred, m_Value(X), m_Not(m_Deferred(X))))) {
+      CmpInst::Predicate PredEqRemoved;
+      Constant *Const;
+      APInt C;
+      switch (Pred) {
+      case ICmpInst::ICMP_EQ:
+        return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
+        break;
+      case ICmpInst::ICMP_NE:
+        return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
+        break;
+      case ICmpInst::ICMP_UGT:
+      case ICmpInst::ICMP_UGE:
+      case ICmpInst::ICMP_ULT:
+      case ICmpInst::ICMP_ULE:
+        PredEqRemoved = CmpInst::getStrictPredicate(Pred);
+        C = APInt::getSignMask(X->getType()->getScalarSizeInBits());
+        C = PredEqRemoved == ICmpInst::ICMP_UGT ? C - 1 : C;
+        Const = ConstantInt::get(X->getType(), C);
----------------
dtcxzyw wrote:

You should emit a signed icmp directly.
```suggestion
        PredEqRemoved = CmpInst::getSwappedPredicate(CmpInst::getSignedPredicate(CmpInst::getStrictPredicate(Pred)));
        Const = PredEqRemoved == ICmpInst::ICMP_SLT ? Constant::getNullValue(X->getType()) : Constant::getAllOnesValue(X->getType());
```


https://github.com/llvm/llvm-project/pull/73990


More information about the llvm-commits mailing list