@@ -1826,7 +1826,6 @@ static Instruction *foldSelectICmpEq(SelectInst &SI, ICmpInst *ICI,
1826
1826
static Value *foldSelectWithConstOpToBinOp (ICmpInst *Cmp, Value *TrueVal,
1827
1827
Value *FalseVal,
1828
1828
IRBuilderBase &Builder) {
1829
- BinaryOperator *BOp;
1830
1829
Constant *C1, *C2, *C3;
1831
1830
Value *X;
1832
1831
CmpPredicate Predicate;
@@ -1842,30 +1841,48 @@ static Value *foldSelectWithConstOpToBinOp(ICmpInst *Cmp, Value *TrueVal,
1842
1841
Predicate = ICmpInst::getInversePredicate (Predicate);
1843
1842
}
1844
1843
1845
- if (!match (TrueVal, m_BinOp (BOp )) || !match (FalseVal, m_Constant (C3) ))
1844
+ if (!match (FalseVal, m_Constant (C3 )) || !TrueVal-> hasOneUse ( ))
1846
1845
return nullptr ;
1847
1846
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 ;
1849
1852
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 ;
1855
1858
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 {
1857
1868
return nullptr ;
1869
+ }
1858
1870
1859
1871
Value *RHS;
1860
1872
SelectPatternFlavor SPF;
1861
- const DataLayout &DL = BOp ->getDataLayout ();
1873
+ const DataLayout &DL = Cmp ->getDataLayout ();
1862
1874
auto Flipped = getFlippedStrictnessPredicateAndConstant (Predicate, C1);
1863
1875
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)) {
1865
1883
SPF = getSelectPattern (Predicate).Flavor ;
1866
1884
RHS = C1;
1867
- } else if (Flipped && C3 == ConstantFoldBinaryOpOperands (
1868
- Opcode, Flipped->second , C2, DL)) {
1885
+ } else if (Flipped && C3 == FoldBinaryOpOrIntrinsic (Flipped->second , C2)) {
1869
1886
SPF = getSelectPattern (Flipped->first ).Flavor ;
1870
1887
RHS = Flipped->second ;
1871
1888
} else {
@@ -1874,7 +1891,9 @@ static Value *foldSelectWithConstOpToBinOp(ICmpInst *Cmp, Value *TrueVal,
1874
1891
1875
1892
Intrinsic::ID IntrinsicID = getMinMaxIntrinsic (SPF);
1876
1893
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);
1878
1897
}
1879
1898
1880
1899
// / Visit a SelectInst that has an ICmpInst as its first operand.
0 commit comments