@@ -1771,26 +1771,38 @@ static Value *foldSelectInstWithICmpConst(SelectInst &SI, ICmpInst *ICI,
17711771 return Builder.CreateBinaryIntrinsic (Intrinsic::smin, V, TVal);
17721772 }
17731773
1774- BinaryOperator *BO;
1774+ // Fold icmp(X) ? f(X) : C to f(X) when f(X) is guaranteed to be equal to C
1775+ // for all X in the exact range of the inverse predicate.
1776+ Instruction *Op;
17751777 const APInt *C;
17761778 CmpInst::Predicate CPred;
1777- if (match (&SI, m_Select (m_Specific (ICI), m_APInt (C), m_BinOp (BO ))))
1779+ if (match (&SI, m_Select (m_Specific (ICI), m_APInt (C), m_Instruction (Op ))))
17781780 CPred = ICI->getPredicate ();
1779- else if (match (&SI, m_Select (m_Specific (ICI), m_BinOp (BO ), m_APInt (C))))
1781+ else if (match (&SI, m_Select (m_Specific (ICI), m_Instruction (Op ), m_APInt (C))))
17801782 CPred = ICI->getInversePredicate ();
17811783 else
17821784 return nullptr ;
17831785
1784- const APInt *BinOpC;
1785- if (!match (BO, m_BinOp (m_Specific (V), m_APInt (BinOpC))))
1786- return nullptr ;
1787-
1788- ConstantRange R = ConstantRange::makeExactICmpRegion (CPred, *CmpC)
1789- .binaryOp (BO->getOpcode (), *BinOpC);
1790- if (R == *C) {
1791- BO->dropPoisonGeneratingFlags ();
1792- return BO;
1786+ ConstantRange InvDomCR = ConstantRange::makeExactICmpRegion (CPred, *CmpC);
1787+ const APInt *OpC;
1788+ if (match (Op, m_BinOp (m_Specific (V), m_APInt (OpC)))) {
1789+ ConstantRange R = InvDomCR.binaryOp (
1790+ static_cast <Instruction::BinaryOps>(Op->getOpcode ()), *OpC);
1791+ if (R == *C) {
1792+ Op->dropPoisonGeneratingFlags ();
1793+ return Op;
1794+ }
1795+ }
1796+ if (auto *MMI = dyn_cast<MinMaxIntrinsic>(Op);
1797+ MMI && MMI->getLHS () == V && match (MMI->getRHS (), m_APInt (OpC))) {
1798+ ConstantRange R = ConstantRange::intrinsic (MMI->getIntrinsicID (),
1799+ {InvDomCR, ConstantRange (*OpC)});
1800+ if (R == *C) {
1801+ MMI->dropPoisonGeneratingAnnotations ();
1802+ return MMI;
1803+ }
17931804 }
1805+
17941806 return nullptr ;
17951807}
17961808
0 commit comments