@@ -1822,7 +1822,6 @@ static Instruction *foldSelectICmpEq(SelectInst &SI, ICmpInst *ICI,
18221822static Value *foldSelectWithConstOpToBinOp (ICmpInst *Cmp, Value *TrueVal,
18231823 Value *FalseVal,
18241824 IRBuilderBase &Builder) {
1825- BinaryOperator *BOp;
18261825 Constant *C1, *C2, *C3;
18271826 Value *X;
18281827 CmpPredicate Predicate;
@@ -1838,30 +1837,48 @@ static Value *foldSelectWithConstOpToBinOp(ICmpInst *Cmp, Value *TrueVal,
18381837 Predicate = ICmpInst::getInversePredicate (Predicate);
18391838 }
18401839
1841- if (!match (TrueVal, m_BinOp (BOp )) || !match (FalseVal, m_Constant (C3) ))
1840+ if (!match (FalseVal, m_Constant (C3 )) || !TrueVal-> hasOneUse ( ))
18421841 return nullptr ;
18431842
1844- unsigned Opcode = BOp->getOpcode ();
1843+ bool IsIntrinsic;
1844+ unsigned Opcode;
1845+ if (BinaryOperator *BOp = dyn_cast<BinaryOperator>(TrueVal)) {
1846+ Opcode = BOp->getOpcode ();
1847+ IsIntrinsic = false ;
18451848
1846- // This fold causes some regressions and is primarily intended for
1847- // add and sub. So we early exit for div and rem to minimize the
1848- // regressions.
1849- if (Instruction::isIntDivRem (Opcode))
1850- return nullptr ;
1849+ // This fold causes some regressions and is primarily intended for
1850+ // add and sub. So we early exit for div and rem to minimize the
1851+ // regressions.
1852+ if (Instruction::isIntDivRem (Opcode))
1853+ return nullptr ;
18511854
1852- if (!match (BOp, m_OneUse (m_BinOp (m_Specific (X), m_Constant (C2)))))
1855+ if (!match (BOp, m_BinOp (m_Specific (X), m_Constant (C2))))
1856+ return nullptr ;
1857+
1858+ } else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(TrueVal)) {
1859+ if (!match (II, m_MaxOrMin (m_Specific (X), m_Constant (C2))))
1860+ return nullptr ;
1861+ Opcode = II->getIntrinsicID ();
1862+ IsIntrinsic = true ;
1863+ } else {
18531864 return nullptr ;
1865+ }
18541866
18551867 Value *RHS;
18561868 SelectPatternFlavor SPF;
1857- const DataLayout &DL = BOp ->getDataLayout ();
1869+ const DataLayout &DL = Cmp ->getDataLayout ();
18581870 auto Flipped = getFlippedStrictnessPredicateAndConstant (Predicate, C1);
18591871
1860- if (C3 == ConstantFoldBinaryOpOperands (Opcode, C1, C2, DL)) {
1872+ auto FoldBinaryOpOrIntrinsic = [&](Constant *LHS, Constant *RHS) {
1873+ return IsIntrinsic ? ConstantFoldBinaryIntrinsic (Opcode, LHS, RHS,
1874+ LHS->getType (), nullptr )
1875+ : ConstantFoldBinaryOpOperands (Opcode, LHS, RHS, DL);
1876+ };
1877+
1878+ if (C3 == FoldBinaryOpOrIntrinsic (C1, C2)) {
18611879 SPF = getSelectPattern (Predicate).Flavor ;
18621880 RHS = C1;
1863- } else if (Flipped && C3 == ConstantFoldBinaryOpOperands (
1864- Opcode, Flipped->second , C2, DL)) {
1881+ } else if (Flipped && C3 == FoldBinaryOpOrIntrinsic (Flipped->second , C2)) {
18651882 SPF = getSelectPattern (Flipped->first ).Flavor ;
18661883 RHS = Flipped->second ;
18671884 } else {
@@ -1870,7 +1887,9 @@ static Value *foldSelectWithConstOpToBinOp(ICmpInst *Cmp, Value *TrueVal,
18701887
18711888 Intrinsic::ID IntrinsicID = getMinMaxIntrinsic (SPF);
18721889 Value *Intrinsic = Builder.CreateBinaryIntrinsic (IntrinsicID, X, RHS);
1873- return Builder.CreateBinOp (BOp->getOpcode (), Intrinsic, C2);
1890+ return IsIntrinsic ? Builder.CreateBinaryIntrinsic (Opcode, Intrinsic, C2)
1891+ : Builder.CreateBinOp (Instruction::BinaryOps (Opcode),
1892+ Intrinsic, C2);
18741893}
18751894
18761895// / Visit a SelectInst that has an ICmpInst as its first operand.
0 commit comments