[llvm] [InstCombine] Improve eq/ne by parts to handle ult/ugt equality pattern (PR #69884)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 4 02:32:30 PDT 2023
================
@@ -1146,13 +1146,41 @@ Value *InstCombinerImpl::foldEqOfParts(ICmpInst *Cmp0, ICmpInst *Cmp1,
return nullptr;
CmpInst::Predicate Pred = IsAnd ? CmpInst::ICMP_EQ : CmpInst::ICMP_NE;
- if (Cmp0->getPredicate() != Pred || Cmp1->getPredicate() != Pred)
- return nullptr;
+ auto GetMatchPart = [&](ICmpInst *Cmp,
+ unsigned OpNo) -> std::optional<IntPart> {
+ if (Pred == Cmp->getPredicate())
+ return matchIntPart(Cmp->getOperand(OpNo));
+
+ const APInt *C;
+ // (icmp eq (lshr x, C), (lshr y, C)) gets optimized to:
+ // (icmp ult (xor x, y), 1 << C) so also look for that.
+ if (Pred == CmpInst::ICMP_EQ && Cmp->getPredicate() == CmpInst::ICMP_ULT) {
+ if (!match(Cmp->getOperand(1), m_Power2(C)) ||
+ !match(Cmp->getOperand(0), m_Xor(m_Value(), m_Value())))
+ return std::nullopt;
+ }
+
+ // (icmp ne (lshr x, C), (lshr y, C)) gets optimized to:
+ // (icmp ugt (xor x, y), (1 << C) - 1) so also look for that.
+ else if (Pred == CmpInst::ICMP_NE &&
+ Cmp->getPredicate() == CmpInst::ICMP_UGT) {
+ if (!match(Cmp->getOperand(1), m_LowBitMask(C)) ||
+ !match(Cmp->getOperand(0), m_Xor(m_Value(), m_Value())))
+ return std::nullopt;
+ } else {
+ return std::nullopt;
+ }
+
+ unsigned From = Pred == CmpInst::ICMP_NE ? C->popcount() : C->countr_zero();
+ Instruction *I = cast<Instruction>(Cmp->getOperand(0));
+ return {{I->getOperand(OpNo), From,
+ Cmp->getOperand(0)->getType()->getScalarSizeInBits() - From}};
----------------
dtcxzyw wrote:
```suggestion
C->getBitWidth() - From}};
```
It would be simpler :)
https://github.com/llvm/llvm-project/pull/69884
More information about the llvm-commits
mailing list