[llvm] [SelectOpt] Add support for AShr/LShr operands (PR #118495)
Igor Kirillov via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 9 07:21:44 PST 2024
================
@@ -784,30 +801,53 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
bool Inverted = match(Cond, m_Not(m_Value(Cond)));
return SelectInfo.insert({I, {Cond, false, Inverted, 0}}).first;
}
-
- // An Or(zext(i1 X), Y) can also be treated like a select, with condition X
- // and values Y|1 and Y.
- if (auto *BO = dyn_cast<BinaryOperator>(I)) {
- switch (I->getOpcode()) {
- case Instruction::Add:
- case Instruction::Sub: {
- Value *X;
- if (!((PatternMatch::match(I->getOperand(0),
- m_OneUse(m_ZExt(m_Value(X)))) ||
- PatternMatch::match(I->getOperand(1),
- m_OneUse(m_ZExt(m_Value(X))))) &&
- X->getType()->isIntegerTy(1)))
+ Value *Val;
+ ConstantInt *Shift;
+ if (match(I, m_Shr(m_Value(Val), m_ConstantInt(Shift))) &&
+ I->getType()->getIntegerBitWidth() == Shift->getZExtValue() + 1) {
+ for (auto *CmpI : SeenCmp) {
+ auto Pred = CmpI->getPredicate();
+ if (Val != CmpI->getOperand(0))
return SelectInfo.end();
- break;
- }
- case Instruction::Or:
- if (BO->getType()->isIntegerTy(1) || BO->getOpcode() != Instruction::Or)
- return SelectInfo.end();
- break;
+ if ((Pred == CmpInst::ICMP_SGT &&
+ match(CmpI->getOperand(1), m_ConstantInt<-1>())) ||
+ (Pred == CmpInst::ICMP_SGE &&
+ match(CmpI->getOperand(1), m_Zero())) ||
+ (Pred == CmpInst::ICMP_SLT &&
+ match(CmpI->getOperand(1), m_Zero())) ||
+ (Pred == CmpInst::ICMP_SLE &&
+ match(CmpI->getOperand(1), m_ConstantInt<-1>()))) {
+ bool Inverted =
+ Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE;
+ return SelectInfo.insert({I, {CmpI, true, Inverted, 0}}).first;
+ }
}
+ }
+
+ // An BinOp(Aux(X), Y) can also be treated like a select, with condition X
+ // and values Y|1 and Y.
+ // `Aux` can be either `ZExt(1bit)` or `XShr(Val), ValBitSize - 1`
+ // `BinOp` can be Add, Sub, Or
+ Value *X;
+ auto MatchZExtPattern = m_c_BinOp(m_Value(), m_OneUse(m_ZExt(m_Value(X))));
+ auto MatchShiftPattern =
+ m_c_BinOp(m_Value(), m_OneUse(m_Shr(m_Value(X), m_ConstantInt(Shift))));
+
+ // This check is unnecessary, but it prevents costly access to the
+ // SelectInfo map.
+ if ((match(I, MatchZExtPattern) && X->getType()->isIntegerTy(1)) ||
+ (match(I, MatchShiftPattern) &&
+ X->getType()->getIntegerBitWidth() == Shift->getZExtValue() + 1)) {
+ if (I->getOpcode() != Instruction::Add &&
+ I->getOpcode() != Instruction::Sub &&
+ I->getOpcode() != Instruction::Or)
+ return SelectInfo.end();
----------------
igogo-x86 wrote:
We match shifts above and then catch Z(S)Exts/Shfits below by checking if operands have SelectLikeInfo.
https://github.com/llvm/llvm-project/pull/118495
More information about the llvm-commits
mailing list