@@ -1826,7 +1826,6 @@ static Instruction *foldSelectICmpEq(SelectInst &SI, ICmpInst *ICI,
18261826static Value *foldSelectWithConstOpToBinOp (ICmpInst *Cmp, Value *TrueVal,
18271827 Value *FalseVal,
18281828 IRBuilderBase &Builder) {
1829- BinaryOperator *BOp;
18301829 Constant *C1, *C2, *C3;
18311830 Value *X;
18321831 CmpPredicate Predicate;
@@ -1842,30 +1841,48 @@ static Value *foldSelectWithConstOpToBinOp(ICmpInst *Cmp, Value *TrueVal,
18421841 Predicate = ICmpInst::getInversePredicate (Predicate);
18431842 }
18441843
1845- if (!match (TrueVal, m_BinOp (BOp )) || !match (FalseVal, m_Constant (C3) ))
1844+ if (!match (FalseVal, m_Constant (C3 )) || !TrueVal-> hasOneUse ( ))
18461845 return nullptr ;
18471846
1848- unsigned Opcode = BOp->getOpcode ();
1847+ bool IsIntrinsic;
1848+ unsigned Opcode;
1849+ if (BinaryOperator *BOp = dyn_cast<BinaryOperator>(TrueVal)) {
1850+ Opcode = BOp->getOpcode ();
1851+ IsIntrinsic = false ;
18491852
1850- // This fold causes some regressions and is primarily intended for
1851- // add and sub. So we early exit for div and rem to minimize the
1852- // regressions.
1853- if (Instruction::isIntDivRem (Opcode))
1854- return nullptr ;
1853+ // This fold causes some regressions and is primarily intended for
1854+ // add and sub. So we early exit for div and rem to minimize the
1855+ // regressions.
1856+ if (Instruction::isIntDivRem (Opcode))
1857+ return nullptr ;
18551858
1856- if (!match (BOp, m_OneUse (m_BinOp (m_Specific (X), m_Constant (C2)))))
1859+ if (!match (BOp, m_BinOp (m_Specific (X), m_Constant (C2))))
1860+ return nullptr ;
1861+
1862+ } else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(TrueVal)) {
1863+ if (!match (II, m_MaxOrMin (m_Specific (X), m_Constant (C2))))
1864+ return nullptr ;
1865+ Opcode = II->getIntrinsicID ();
1866+ IsIntrinsic = true ;
1867+ } else {
18571868 return nullptr ;
1869+ }
18581870
18591871 Value *RHS;
18601872 SelectPatternFlavor SPF;
1861- const DataLayout &DL = BOp ->getDataLayout ();
1873+ const DataLayout &DL = Cmp ->getDataLayout ();
18621874 auto Flipped = getFlippedStrictnessPredicateAndConstant (Predicate, C1);
18631875
1864- if (C3 == ConstantFoldBinaryOpOperands (Opcode, C1, C2, DL)) {
1876+ auto FoldBinaryOpOrIntrinsic = [&](Constant *LHS, Constant *RHS) {
1877+ return IsIntrinsic ? ConstantFoldBinaryIntrinsic (Opcode, LHS, RHS,
1878+ LHS->getType (), nullptr )
1879+ : ConstantFoldBinaryOpOperands (Opcode, LHS, RHS, DL);
1880+ };
1881+
1882+ if (C3 == FoldBinaryOpOrIntrinsic (C1, C2)) {
18651883 SPF = getSelectPattern (Predicate).Flavor ;
18661884 RHS = C1;
1867- } else if (Flipped && C3 == ConstantFoldBinaryOpOperands (
1868- Opcode, Flipped->second , C2, DL)) {
1885+ } else if (Flipped && C3 == FoldBinaryOpOrIntrinsic (Flipped->second , C2)) {
18691886 SPF = getSelectPattern (Flipped->first ).Flavor ;
18701887 RHS = Flipped->second ;
18711888 } else {
@@ -1874,7 +1891,9 @@ static Value *foldSelectWithConstOpToBinOp(ICmpInst *Cmp, Value *TrueVal,
18741891
18751892 Intrinsic::ID IntrinsicID = getMinMaxIntrinsic (SPF);
18761893 Value *Intrinsic = Builder.CreateBinaryIntrinsic (IntrinsicID, X, RHS);
1877- return Builder.CreateBinOp (BOp->getOpcode (), Intrinsic, C2);
1894+ return IsIntrinsic ? Builder.CreateBinaryIntrinsic (Opcode, Intrinsic, C2)
1895+ : Builder.CreateBinOp (Instruction::BinaryOps (Opcode),
1896+ Intrinsic, C2);
18781897}
18791898
18801899// / Visit a SelectInst that has an ICmpInst as its first operand.
0 commit comments