@@ -419,6 +419,20 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
419419 if (match (Op0, m_FNeg (m_Value (X))) && match (Op1, m_FNeg (m_Value (Y))))
420420 return BinaryOperator::CreateFMulFMF (X, Y, &I);
421421
422+ // pow(X, A) * pow(X, B) -> pow(X, A+B)
423+ Value *A, *B;
424+ if (I.hasAllowReassoc () && Op0->hasOneUse () && Op1->hasOneUse ()) {
425+ if (match (Op0, m_Intrinsic<Intrinsic::pow>(m_Value (X), m_Value (A))) &&
426+ match (Op1, m_Intrinsic<Intrinsic::pow>(m_Value (Y), m_Value (B)))) {
427+ if (X == Y) {
428+ Value *AddAB = Builder.CreateFAddFMF (A, B, &I);
429+ Value *Pow = Builder.CreateBinaryIntrinsic (Intrinsic::pow, X, AddAB,
430+ cast<IntrinsicInst>(Op0));
431+ return replaceInstUsesWith (I, Pow);
432+ }
433+ }
434+ }
435+
422436 // -X * C --> X * -C
423437 Constant *C;
424438 if (match (Op0, m_FNeg (m_Value (X))) && match (Op1, m_Constant (C)))
@@ -1270,6 +1284,18 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) {
12701284 Res = B.CreateFDiv (ConstantFP::get (I.getType (), 1.0 ), Res);
12711285 return replaceInstUsesWith (I, Res);
12721286 }
1287+
1288+ // pow(X, A) / pow(X, B) -> pow(X, A-B)
1289+ Value *Y, *A, *B;
1290+ if (match (Op0, m_Intrinsic<Intrinsic::pow>(m_Value (X), m_Value (A))) &&
1291+ match (Op1, m_Intrinsic<Intrinsic::pow>(m_Value (Y), m_Value (B)))) {
1292+ if (X == Y) {
1293+ Value *SubAB = Builder.CreateFSubFMF (A, B, &I);
1294+ Value *Pow = Builder.CreateBinaryIntrinsic (Intrinsic::pow, X, SubAB,
1295+ cast<IntrinsicInst>(Op0));
1296+ return replaceInstUsesWith (I, Pow);
1297+ }
1298+ }
12731299 }
12741300
12751301 // -X / -Y -> X / Y
0 commit comments