[llvm] [InstCombine] simplify `x (comp) ~x` (PR #73990)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 30 14:12:02 PST 2023


================
@@ -7035,6 +7035,63 @@ 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>  ~X
+    //           X s<= ~X  -->   X s<  ~X
+    //           X u<  ~X  -->   X u<  (SIGNBIT(X))
+    //           X u>  ~X  -->   X u>  (SIGNBIT(X))
+    //           X u<= ~X  -->   X u<  (SIGNBIT(X))
+    //           X u>= ~X  -->   X u>  (SIGNBIT(X))
+    //           X ==  ~X  -->   false
+    //           X !=  ~X  -->   true
+    if (match(&I, m_c_ICmp(Pred, m_Value(X), m_Value(Y))) &&
+        (match(X, m_c_Xor(m_Specific(Y), m_AllOnes())) ||
+         match(Y, m_c_Xor(m_Specific(X), m_AllOnes())))) {
+      //  ~X s< X   -->     X s> ~X
+      //  ~X s> X   -->     X s< ~X
+      //  ~X u< X   -->     X u> ~X
+      //  ~X u> X   -->     X u< ~X
+      if (match(X, m_c_Xor(m_Specific(Y), m_AllOnes()))) {
+        Pred = I.getSwappedPredicate();
+        std::swap(X, Y);
+      }
+
+      Constant *Const;
+      APInt C(X->getType()->getScalarSizeInBits(), 0);
+      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:
+        Pred =
+            Pred < ICmpInst::ICMP_ULT ? ICmpInst::ICMP_UGT : ICmpInst::ICMP_ULT;
+        C.setSignBit();
----------------
nikic wrote:

APInt::getSignMask()

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


More information about the llvm-commits mailing list