[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